clip Posted November 25, 2009 Posted November 25, 2009 Hi, I'm working on a socket debugger, I know there are plenty of this around, but I want to learn how to make my own in MASM32. Initially I'm trying to hook the "send" function from wsock32.dll then open firefox. I would like to replace the information being sent by firefox with "Gotcha". I used jaghook for this. So far it's not working. Does anyone have a clue why?replace.asm.486.model flat, stdcalloption casemap: noneinclude \masm32\include\windows.incinclude \masm32\include\kernel32.incinclude \masm32\include\user32.incinclude \masm32\include\wsock32.incincludelib \masm32\lib\kernel32.libincludelib \masm32\lib\user32.libincludelib \masm32\lib\wsock32.libinclude jagHook.inc .data module db "wsock32.dll", 0 procname db "send", 0 newtext db "Gotcha", 0 CMD db "c:\program files\mozilla firefox\firefox.exe",0 sinfo STARTUPINFO <> pinfo PROCESS_INFORMATION <> .data? pmsenddetour db StubLen(5) dup (?) .code ; 5 bytes need to be replaced for MessageBoxA ; 77D804EA > 8BFF MOV EDI,EDI ; 77D804EC 55 PUSH EBP ; 77D804ED 8BEC MOV EBP,ESP MySendHook proc sock:SOCKET, Body:LPCTSTR, uType1:UINT, uType2:UINT invoke pr4 PTR pmsenddetour, sock, OFFSET newtext, 6, uType2 ret MySendHook endp start: invoke GetModuleHandle, OFFSET module invoke GetProcAddress, eax, OFFSET procname ; do some hook demonstrations invoke ProcInstallHook, MySendHook, eax, OFFSET pmsenddetour, 5 invoke send, 0,0,0,0 invoke CreateProcess, ADDR CMD, NULL, NULL, NULL, NULL, 0, 0,0,addr sinfo,addr pinfo invoke Sleep, 600000 invoke ProcUninstallHook, OFFSET pmsenddetour, 5 ret end startjaghook.inc:comment *========================================== jagHook by jAgx Note that: macros are like win32 api; they may modify all registers but ebx, edi, esi your .text section needs to be writable if using the non-procedural hooking if using radasm, add /SECTION:.text|RWE the LINK box under Project -> Project Options] otherwise, just add /SECTION:.text,RWE to linking arguments Usage Below BeginHook & EndHook -------------------- This pair of macros creates a hook procedure. HookName is a unique identifier you choose for your hook PatchLength is the number of bytes (must be >= 5) that will be emulated >= 5 because the hook jmp is 5 bytes long so need at least 5 bytes to fit it if PatchLength is left out, it will default to 5 DoPushPop - if this optional argument is TRUE, push ebx,edi,esi and pop ebx,edi,esi are placed in the beginning and end of your hook, respectively. Use it to make code cleaner or type less when needed. Most of the time you will need to use push ebx,edi,esi and pop ebx,edi,esi since you shouldn't have any crucial registers changed when handing control back to the hooked procedure. BeginHook HookName[, PatchLength][, DoPushPop] ...code... EndHook ------------------------------------------- InstallHook ------------ This macro hooks a target function. HookName is the unique identifier of the hook you previously created TargetProcedure is the procedure to hook onto InstallHook HookName, TargetProcedure ------------------------------------------- ReinstallHook -------------- This macro hooks the target function previously hooked by HookName HookName is the unique identifier of the hook you previously created ReinstallHook HookName ------------------------------------------- UninstallHook -------------- This macro clears the hook from the procedure it is attached to. HookName is the unique identifier of the hook you previously created UninstallHook HookName ------------------------------------------- StubLen ------------ This macro returns the # of bytes needed to create a stub, given the patch length. PatchLength is how many bytes will be emulated StubLen PatchLength ------------------------------------------- ProcInstallHook ----------------------- This procedure hooks the target function and returns a pointer to an allocated stub which can be used to call the original function. HookProcedure is the procedure which the target will be redirected to TargetProcedure is the target procedure to hook into DetourStub is a pointer to a buffer of length StubLen(PatchLength) PatchLength is how many bytes will be emulated invoke ProcInstallHook, HookProcedure, TargetProcedure, DetourStub, PatchLength ------------------------------------------- ProcReinstallHook ------------------------- This procedure reinstalls a hook on a target function without allocating another stub HookProcedure is the procedure which the target will be redirected to DetourStub is a pointer to the stub previously used by a call to ProcInstallHook PatchLength is the amount of bytes that were emulated Note: HookProcedure does not need to be the same one that was used to create the stub Note: TargetProc is not needed since the stub pointer will be used to calculate it invoke ProcReinstallHook, HookProcedure, DetourStub, PatchLength ------------------------------------------- ProcUninstallHook ----------------------- This procedure uninstalls a hook that was previously installed. DetourStub is a pointer to the stub previously used by a call to ProcInstallHook PatchLength is the amount of bytes that were emulated Note: TargetProc is not needed since the stub pointer will be used to calculate it. invoke ProcUninstallHook, DetourStub, PatchLength ------------------------------------------- Examples Example 1 ; This example hijacks the text of messageboxes using non-procedural hooking (faster performance-wise) .data module db "user32.dll", 0 procname db "MessageBoxA", 0 normaltext db "woooot my text!!!", 0 newtext db "Stole your messagebox!", 0 .code ; 5 bytes need to be replaced for MessageBoxA ; 77D804EA > 8BFF MOV EDI,EDI ; 77D804EC 55 PUSH EBP ; 77D804ED 8BEC MOV EBP,ESP ; we want to change the text (3nd parameter = 8 byte offset) ; return address is on stack (4 bytes) ; push ebp will be executed (ebp on stack <--- esp) ; so the text address is stored in esp + 12 BeginHook MyMsgBoxHook, 5 mov [esp + 12], OFFSET newtext EndHook start: ; get address of MessageBoxA invoke GetModuleHandle, OFFSET module invoke GetProcAddress, eax, OFFSET procname ; do some hook demonstrations InstallHook MyMsgBoxHook, eax invoke MessageBox, NULL, OFFSET normaltext, NULL, MB_OK ; we should see modified title UninstallHook MyMsgBoxHook invoke MessageBox, NULL, OFFSET normaltext, NULL, MB_OK ; we should see normal title ReinstallHook MyMsgBoxHook invoke MessageBox, NULL, OFFSET normaltext, NULL, MB_OK ; we should see modified title ret end start Example 2 ; This example hijacks the text of messageboxes using procedural hooking (easier - less headaches) .data module db "user32.dll", 0 procname db "MessageBoxA", 0 normaltext db "woooot my text!!!", 0 newtext db "Stole your messagebox!", 0 .data? pMBoxDetour db StubLen(5) dup (?) .code ; 5 bytes need to be replaced for MessageBoxA ; 77D804EA > 8BFF MOV EDI,EDI ; 77D804EC 55 PUSH EBP ; 77D804ED 8BEC MOV EBP,ESP MyMsgBoxHook proc hWnd:HWND, lpText:LPCTSTR, lpCaption:LPCTSTR, uType:UINT invoke pr4 PTR pMBoxDetour, hWnd, OFFSET newtext, lpCaption, uType ret MyMsgBoxHook endp start: ; get address of MessageBoxA invoke GetModuleHandle, OFFSET module invoke GetProcAddress, eax, OFFSET procname ; do some hook demonstrations invoke ProcInstallHook, MyMsgBoxHook, eax, OFFSET pMBoxDetour, 5 invoke MessageBox, NULL, OFFSET normaltext, NULL, MB_OK ; we should see modified title invoke ProcUninstallHook, OFFSET pMBoxDetour, 5 invoke MessageBox, NULL, OFFSET normaltext, NULL, MB_OK ; we should see normal title invoke ProcReinstallHook, MyMsgBoxHook, OFFSET pMBoxDetour, 5 invoke MessageBox, NULL, OFFSET normaltext, NULL, MB_OK ; we should see modified title ret end start*========================================================InstallHook macro hookName:REQ, targetProc:REQ invoke pInstallHook, OFFSET jagHookBegin_&hookName, jagHookEnd_&hookName, targetProc, SIZEOF jagHookBegin_&hookNameendmReinstallHook macro hookName:REQ invoke pReinstallHook, OFFSET jagHookBegin_&hookName, jagHookEnd_&hookName, SIZEOF jagHookBegin_&hookNameendmUninstallHook macro hookName:REQ invoke pUninstallHook, OFFSET jagHookBegin_&hookName, jagHookEnd_&hookName, SIZEOF jagHookBegin_&hookNameendmBeginHook macro hookName:REQ, patchLen:=<5>, doPushPop jagHookName TEXTEQU <hookName> jagHookDoPushPop TEXTEQU <doPushPop> jagHookBegin_&hookName db patchLen dup (?) if doPushPop push ebx push edi push esi push ebp endifendmEndHook macro if jagHookDoPushPop pop ebp pop esi pop edi pop ebx endif db 0E9h dd ?% jagHookEnd_&jagHookName:endmStubLen macro patchLen:REQ exitm <patchLen + 5>endm.codepInstallHook proc uses ebx edi esi hookBegin:DWORD, hookEnd:DWORD, targetProc:DWORD, patchLen:DWORD mov edi, targetProc mov esi, patchLen mov ebx, hookBegin ; make the target writable invoke VirtualProtect, edi, 5, PAGE_EXECUTE_READWRITE, ADDR hookBegin ; copy the to-be-emulated bytes from targetProc to hook's beginning invoke RtlMoveMemory, ebx, edi, esi ; replace the bytes with a jmp to the hook sub ebx, 5 sub ebx, edi mov BYTE PTR [edi], 0E9h mov [edi + 1], ebx ; put a jmp to the targetProc at the end of hook mov ebx, hookEnd ; set protections back to old ones to avoid complications invoke VirtualProtect, edi, 5, hookBegin, ADDR hookBegin sub edi, ebx add edi, esi mov [ebx - 4], edi retpInstallHook endppReinstallHook proc uses ebx hookBegin:DWORD, hookEnd:DWORD, patchLen:DWORD ; get address of targetProc mov eax, hookEnd mov ebx, [eax - 4] add ebx, eax sub ebx, patchLen ; make the target writable invoke VirtualProtect, ebx, 5, PAGE_EXECUTE_READWRITE, ADDR hookEnd ; replace the starting bytes with a jmp to the hook mov eax, hookBegin sub eax, 5 sub eax, ebx mov BYTE PTR [ebx], 0E9h mov [ebx + 1], eax ; set protections back to old ones to avoid complications invoke VirtualProtect, ebx, 5, hookEnd, ADDR hookEnd retpReinstallHook endppUninstallHook proc uses ebx hookBegin:DWORD, hookEnd:DWORD, patchLen:DWORD ; get address of targetProc mov eax, hookEnd mov ebx, [eax - 4] add ebx, eax sub ebx, patchLen ; make the target writable invoke VirtualProtect, ebx, 5, PAGE_EXECUTE_READWRITE, ADDR hookEnd ; copy the emulated bytes from hook back to targetProc, replacing the jmp mov eax, hookBegin mov ecx, [eax] mov dl, BYTE PTR [eax + 4] mov [ebx], ecx mov BYTE PTR [ebx + 4], dl ; set protections back to old ones to avoid complications invoke VirtualProtect, ebx, 5, hookEnd, ADDR hookEnd retpUninstallHook endpProcInstallHook proc uses ebx edi esi hookProc:DWORD, targetProc:DWORD, pDetour:DWORD, patchLen:DWORD mov edi, targetProc mov esi, patchLen mov ebx, pDetour ; make the target writable invoke VirtualProtect, edi, 5, PAGE_EXECUTE_READWRITE, ADDR targetProc ; copy the to-be-emulated bytes from targetProc to detour's beginning invoke RtlMoveMemory, ebx, edi, esi ; replace the bytes with a jmp to the hook mov eax, hookProc sub eax, edi sub eax, 5 mov BYTE PTR [edi], 0E9h mov [edi + 1], eax ; put a jmp to the targetProc at the end of detour add esi, ebx ; set protections back to old ones to avoid complications invoke VirtualProtect, edi, 5, targetProc, ADDR targetProc sub edi, ebx sub edi, 5 mov BYTE PTR [esi], 0E9h mov [esi + 1], edi retProcInstallHook endp ProcReinstallHook proc uses ebx hookProc:DWORD, pDetour:DWORD, patchLen:DWORD ; get address of targetProc mov eax, pDetour mov ecx, patchLen mov ebx, [eax + ecx + 1] add ebx, eax add ebx, 5 ; make the target writable invoke VirtualProtect, ebx, 5, PAGE_EXECUTE_READWRITE, ADDR pDetour ; replace the starting bytes with a jmp to the hook mov eax, hookProc sub eax, 5 sub eax, ebx mov BYTE PTR [ebx], 0E9h mov [ebx + 1], eax ; set protections back to old ones to avoid complications invoke VirtualProtect, ebx, 5, pDetour, ADDR pDetour retProcReinstallHook endpProcUninstallHook proc uses ebx edi pDetour:DWORD, patchLen:DWORD ; get address of targetProc mov ebx, pDetour mov eax, patchLen mov edi, [ebx + eax + 1] add edi, ebx add edi, 5 ; make the target writable invoke VirtualProtect, edi, 5, PAGE_EXECUTE_READWRITE, ADDR pDetour ; copy the emulated bytes from hook back to targetProc, replacing the jmp mov eax, [ebx] mov cl, BYTE PTR [ebx + 4] mov [edi], eax mov BYTE PTR [edi + 4], cl ; set protections back to old ones to avoid complications invoke VirtualProtect, edi, 5, pDetour, ADDR pDetour retProcUninstallHook endpSample codes for MS' detour, IAT manipulation and API Hooking in MASM would be greately appreciated. (Does anyone have an asm example using ELiCZ's lib?)Thank you.
human Posted November 26, 2009 Posted November 26, 2009 (edited) if i remember correctly, once i did a hooker to log all api and wsock didnt work due it checks if its not hooked.so you need to get around it.and btw i see you hook send,use send and you said you want to hook send inside firefox, well hook is only local. will not work in another process when you start firefox with createprocess. you need to hook it inside firefox. well you dont if you use crap win9x that shares dll's:Pto create better hook, use dll injection. a lot easier to code,no need to take care of replacing code,adresses,load proper dll's for hook.and another thing this hook engine is ****, code your own hooker,for this case you want gotcha to replace send api. so you dont need original api code.but in other cases you need bytes that you replace to run after hook. so you need run lenght disasm to tell you how many bytes copy and where set return from hook to code due instructions that E9 jump will replace will not always be 5 bytes long. Edited November 26, 2009 by human
clip Posted November 26, 2009 Author Posted November 26, 2009 if i remember correctly, once i did a hooker to log all api and wsock didnt work due it checks if its not hooked.so you need to get around it.and btw i see you hook send,use send and you said you want to hook send inside firefox, well hook is only local. will not work in another process when you start firefox with createprocess. you need to hook it inside firefox. well you dont if you use crap win9x that shares dll's:PI am not much of a coder, but I'm working on it. Thanks for the reply.there's not much resource i could find about this that is masm-specific. they red-flag and shoot this type of topic over at masm32.com. I hooked send then used send (invoke send, 0,0,0,0) because for some reason the program crashes if you don't use the function being hooked. How do I hook this inside firefox? Can you please point me to a masm-specific resource if you have any? I'm running this on NT-based OS (XP-VISTA).to create better hook, use dll injection. a lot easier to code,no need to take care of replacing code,adresses,load proper dll's for hook.and another thing this hook engine is ****, code your own hooker,for this case you want gotcha to replace send api. so you dont need original api code.but in other cases you need bytes that you replace to run after hook. so you need run lenght disasm to tell you how many bytes copy and where set return from hook to code due instructions that E9 jump will replace will not always be 5 bytes long.just to clear things up I do not intend to use this for malware, I just wanted to code my own "socket debugger" type of program. There are plenty of this type of program available online and I wanted to "reinvent the wheel" to see how it works and learn. I was thinking the "legal" way of doing this, like most debuggers do, is to launch the program to be debugged with it, or as you said, hook it inside the app. I just don't know how to do this. If DLL injection is the better way then I'll take it. I've read about injecting jumps (E9xxxx), IAT manipulation, but they are all theories, I don't know how to put it in code.Thanks again.
human Posted November 26, 2009 Posted November 26, 2009 there was app long time ago called sockscap,that was in delphi and asm,used dll injection. so you can use socks proxy tunnel in any app. it came with sourcecode. you can try to find it or other stuff on google.
wunder Posted March 31, 2011 Posted March 31, 2011 (edited) -----=Edited=----- Edited April 2, 2011 by wunder
ghandi Posted March 31, 2011 Posted March 31, 2011 I'm sorry, but when i first read your post my immediate thought was: "Hmmm, why resurrect a dead thread? (Posted 26 November 2009)", but this was quickly followed by "Okay, the poster has included some sources that others can use when faced with this problem themselves.".Now i've taken the time to download both sources and examine them, i have revised again my thoughts. Both sources have absolutely nothing to do with the original posters problem or with the solution, instead they are an open source r.a.t and an example http downloader from Iczelion's MASM Win32 tutorials.Can i ask then, why on earth would these sources be relevant to API hooking using MASM code, aside from the obvious fact they share API names and one could get argument lists from the use of such API? The latter is something which MSDN could provide and the former is meaningless, maybe to share such code simply a fresh thread in the coding section would have sufficed?HR,Ghandi
wunder Posted April 2, 2011 Posted April 2, 2011 <br />I'm sorry, but when i first read your post my immediate thought was: "Hmmm, why resurrect a dead thread? (Posted 26 November 2009)", but this was quickly followed by "Okay, the poster has included some sources that others can use when faced with this problem themselves.".<br /><br />Now i've taken the time to download both sources and examine them, i have revised again my thoughts. Both sources have absolutely nothing to do with the original posters problem or with the solution, instead they are an open source r.a.t and an example http downloader from Iczelion's MASM Win32 tutorials.<br /><br />Can i ask then, why on earth would these sources be relevant to API hooking using MASM code, aside from the obvious fact they share API names and one could get argument lists from the use of such API? The latter is something which MSDN could provide and the former is meaningless, maybe to share such code simply a fresh thread in the coding section would have sufficed?<br /><br />HR,<br />Ghandi<br /><br /><br /><br />My sincere apologies, from reading the posters .asm it seemed like what I posted could be another way of what he was trying to accomplish very sorry about that...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now