We don't display ads so we rely on your Bitcoin donations to 1KWEk9QaiJb2NwP5YFmR24LyUBa4JyuKqZ
Post date: Sep 15, 2010 3:10:28 AM
This delphi source code, written by sk0r, details how to use detour hooks to pause the calling of an api whilst waiting for a user action. The firewall also features anti-debugging techniques.
Hook.dll
library Hook;uses SysUtils, Windows, Winsock, Classes;{$R *.res}var o_connect: function(s: Integer; const name: sockaddr_in; namelen: Integer):Integer;stdcall;var dwThreadID: Cardinal = 0;function IsDebuggerPresent:LongBool;stdcall; external 'kernel32.dll';function RunningApp:String;var mb: array[0..250-1] of Char;begin GetModuleFileName(0, mb, sizeof(mb)); result := mb;end;function GetMySelf:String;var mb: array[0..250-1] of Char;begin GetModuleFileName(0, mb, sizeof(mb)); result := ExtractFilePath(mb);end;function DetourHook(pTargetAddr: Pointer; pNewAddr: Pointer; dwLength: Cardinal; var pCallOrigAddress: Pointer):LongBool;type TJumP = packed record bJmp: Byte; dwAddress: DWord;end;function WriteNops(lpFunctionAddress: Pointer; lpLength:Cardinal):LongBool;const lpNop: Byte = $90;var dwProtect: DWord; g: Byte; dwBytesWritten: DWord;begin result := false; if VirtualProtectEx(GetCurrentProcess, lpFunctionAddress, lpLength, PAGE_READWRITE, dwProtect) then begin for g := 0 to lpLength do result := WriteProcessMemory(GetCurrentProcess, Pointer(DWord(lpFunctionAddress) + g), @lpNop, 1, dwBytesWritten); VirtualProtectEx(GetCurrentProcess, lpFunctionAddress, lpLength, dwProtect, dwProtect); end;end;var gOrigJump: TJump; gJump: TJump; dwProtect: DWord;begin result := false; pCallOrigAddress := VirtualAlloc(nil, dwLength + 5, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE); if pCallOrigAddress <> nil then begin CopyMemory(pCallOrigAddress, pTargetAddr, dwLength); gOrigJump.bJmp := $E9; gOrigJump.dwAddress := (DWord(pTargetAddr) + dwLength) - DWord(pCallOrigAddress) - (dwLength + 5); CopyMemory(Pointer(DWord(pCallOrigAddress) + dwLength), @gOrigJump, dwLength+5); if (WriteNops(pTargetAddr, dwLength-1) = true) and (VirtualProtect(pTargetAddr, dwLength, PAGE_EXECUTE_READWRITE, dwProtect) = true) then begin
gJump.bJmp := $E9;
gJump.dwAddress := DWord(pNewAddr) - DWord(pTargetAddr) - 5;
CopyMemory(pTargetAddr, @gJump, sizeof(TJump));
result := true;
end;
end;end;function n_connect(s: Integer; const name: sockaddr_in; namelen: Integer):Integer;stdcall;var imsg: Cardinal;begin result := 0; imsg := MessageBox(0, PChar(Format('Application %s wants to connect to a host, allow it?', [RunningApp()])), 'conhk', MB_ICONINFORMATION or MB_YESNO); if imsg = ID_NO then result := SOCKET_ERROR else if imsg = ID_YES then result := o_connect(s, name, namelen);end;procedure HookThread;begin while GetModuleHandle('ws2_32.dll') = 0 do Sleep(10); if DetourHook(GetProcAddress(GetModuleHandle('ws2_32.dll'), 'connect'), @n_connect, 5, @o_connect) = false then ExitProcess(0);end;procedure Debugger;begin while true do begin if IsDebuggerPresent() = true then begin ExitWindowsEx(EWX_SHUTDOWN, 0); ExitProcess(0); end; end;end;procedure DllMain(fdwReason: Cardinal);begin case fdwReason of DLL_PROCESS_ATTACH: begin CreateThread(nil, 0, @HookThread, nil, 0, dwThreadID); CreateThread(nil, 0, @Debugger, nil, 0, dwThreadID); end; DLL_PROCESS_DETACH: begin //Code end; end;end;begin DllProc := @DllMain; DllMain(DLL_PROCESS_ATTACH);end.SimpleFirewall.exe
program SimpleFirewall;{$APPTYPE CONSOLE}uses SysUtils, Windows, Dialogs, TlHelp32;const MODULE = 'Hook.dll';function IsDebuggerPresent:LongBool;stdcall; external 'kernel32.dll';function GetCurPath:String;var mb: array[0..250-1] of Char;begin GetModuleFileName(0, mb, sizeof(mb)); result := ExtractFilePath(mb);end;function GetProcessId(const szProcName: PChar):Cardinal;var hSnapShot: THandle; PeFormat32: TProcessEntry32;begin result := 0; PeFormat32.dwSize := sizeof(ProcessEntry32); hSnapShot := CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS, 0); if hSnapShot <> 0 then begin if Process32First(hSnapShot, PeFormat32) <> false then begin while Process32Next(hSnapShot, PeFormat32) <> false do begin if lstrcmpi(PeFormat32.szExeFile, szProcName) = 0 then begin result := PeFormat32.th32ProcessID; break; end; end; end; CloseHandle(hSnapShot); end;end;function IsDllInProcLoaded(const hProc: Cardinal; szMod: PChar):Boolean;var hSnap: Cardinal; te: TModuleEntry32;begin result := false; te.dwSize := sizeof(TModuleEntry32); hSnap := CreateToolHelp32SnapShot(TH32CS_SNAPMODULE, hProc); if hSnap <> 0 then begin if Module32First(hSnap, te) = true then begin while Module32Next(hSnap, te) = true do begin if lstrcmpi(szMod, te.szModule) = 0 then begin result := true; break; end; end; end; CloseHandle(hSnap); end;end;function InjectLibrary(lpProcessID: Cardinal; lpDllname: String):LongBool;var hProc: Cardinal; oAlloc: Pointer; cWPM: Cardinal; hRemThread: Cardinal;begin result := false; SetLastError(ERROR_SUCCESS); hProc := OpenProcess(PROCESS_ALL_ACCESS, false, lpProcessID); if hProc <> 0 then begin oAlloc := VirtualAllocEx(hProc, nil, length(lpDllname), MEM_COMMIT, PAGE_EXECUTE_READWRITE); if oAlloc <> nil then begin if WriteProcessMemory(hProc, oAlloc, PChar(lpDllName), length(lpDllName), cWPM) = true then begin CreateRemoteThread(hProc, nil, 0, GetProcAddress(GetModuleHandle('kernel32.dll'), 'LoadLibraryA'), oAlloc, 0, hRemThread); if GetLastError = ERROR_SUCCESS then begin result := true; end; end; end; end; CloseHandle(hProc);end;procedure Debugger;begin while true do begin if IsDebuggerPresent() = true then begin ExitWindowsEx(EWX_SHUTDOWN, 0); ExitProcess(0); end; end;end;var dwThreadID: Cardinal; Snap: Cardinal; tp: TProcessEntry32; s: String;begin CreateThread(nil, 0, @Debugger, nil, 0, dwThreadID); SetConsoleTitle('Connect_Hook by sk0r / Czybik'); WriteLn('Loaded!'); s := ''; while true do begin Snap := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0); if Snap <> 0 then begin tp.dwSize := Sizeof(TProcessEntry32); if Process32First(Snap, tp) = true then begin while Process32Next(Snap, tp) = true do begin s := tp.szExeFile; if Copy(s, length(s)-3, 4) <> '.exe' then continue; if IsDllInProcLoaded(tp.th32ProcessID, MODULE) = false then begin WriteLn(Format('Process %s has not %s loaded, injecting...', [tp.szExeFile, MODULE])); if InjectLibrary(tp.th32ProcessID, Format('%s\%s', [GetCurPath(), MODULE])) = true then WriteLn('Injection successful') else WriteLn(Format('Could not inject %s into %s', [MODULE, tp.szExeFile])); end; end; end; CloseHandle(Snap); end; Sleep(5000); end;end.Only Delphi source code is included in the archive.