.::God::. Posted March 28, 2008 Posted March 28, 2008 Can someone give me an example in Delphi/ASM on how to write a loader: That breaks on the first DefWindowProcA, modifies an address and then resumes process. Just some example code will do, thanks.
Armaked0n Posted March 28, 2008 Posted March 28, 2008 check this tutorial, it might help you :/>http://arteam.accessroot.com/tutorials.html?fid=81
.::God::. Posted March 28, 2008 Author Posted March 28, 2008 Already read that, but it didnt help much.
What Posted March 28, 2008 Posted March 28, 2008 (edited) Here try something like this:ProcessInfo PROCESS_INFORMATION <>align dwordpContext CONTEXT <>Patch db EBh, FEhOriginal dd ?VAEntryPoint dd ?VADefWindowProcA dd ?Invoke CreateProcess, _target,0,0,0,0,CREATE_SUSPENDED,0,0,0, offset ProcessInfoInvoke WriteProcessMemory, ProcessInfo.hProcess, VAEntryPoint, offset Patch, 2, 0Invoke ResumeThread, ProcessInfo.hThread.while TRUEInvoke GetThreadContext, ProcessInfo.hThread, offset pContextPush pContext.regEippop eax.break .if eax == VAEntryPoint.endwInvoke SuspendThread, ProcessInfo.hThreadInvoke WriteProcessMemory,ProcessInfo.hProcess, VAEntryPoint, offset Original, 2, 0Invoke WriteProcessMemory, ProcessInfo.hProcess, VADefWindowProcA, offset Patch, 2, 0Invoke ResumeThread, ProcessInfo.hThread.while TRUEInvoke GetThreadContext, ProcessInfo.hThread, offset pContextPush pContext.regEippop eax.break .if eax == VADefWindowProcA.endwInvoke SuspendThread, ProcessInfo.hThreadInvoke WriteProcessMemory,ProcessInfo.hProcess, VADefWindowProcA, offset Original, 2, 0////////////////////////////////////////////////////////////////////////////////////////////////////////Do your work////////////////////////////////////////////////////////////////////////////////////////////////////////Invoke ResumeThread, ProcessInfo.hThreadInvoke ExitProcess, 0Something like that should work fine. Obviously this is not a complete example, you'll have to get original bytes and addresses, also mov pContext.ContextFlags, 1001Fh before GetThreadContext calls, otherwise it wont work. Edited March 29, 2008 by What
Departure Posted March 29, 2008 Posted March 29, 2008 (edited) Here is sample of how I do my loaders in delphi, Im still looking for my asm example and when i find it I will post itconst { Address's to write multi Patch1 and Patch2 } MultiAddress1=$0054DCEB; MultiAddress2=$0054DCF7; { Address to write Patch3 } Address3=$004F47E9; { Address to write Patch4 } Address4=$00539D44; { Address to write Patch5 } Address5=$00463315; { Bytes to write } MultiPatch1 : array[1..2] of byte = ($EB,$08); MultiPatch2 : array[1..6] of byte = ($BB,$00,$00,$00,$00,$90); Patch3 : array[1..6] of byte = ($90,$90,$90,$90,$90,$90); Patch4 : array[1..2] of byte = ($EB,$20); Patch5 : array[1..2] of byte = ($EB,$18);{$R *.dfm}procedure TForm1.Button1Click(Sender: TObject);var { Startup and variables used in procedure } Path : String; StartInfo : TStartupInfo; ProcInfo : TProcessInformation; CreateOK : Boolean; Write: Cardinal;begin Path:= 'C:\Myprogram.exe' FillChar(StartInfo,SizeOf(TStartupInfo),#0); FillChar(ProcInfo,SizeOf(TProcessInformation),#0); StartInfo.cb := SizeOf(TStartupInfo); CreateOK := CreateProcess(PChar(Path),nil, nil, nil,False,CREATE_SUSPENDED,nil, nil, StartInfo, ProcInfo); { check to see if successful }if CreateOK then begin{ ----------------------------------------------------------------------- } { Write Patch1 and Patch2 to memory } WriteProcessMemory(ProcInfo.hProcess,ptr(MultiAddress1),@MultiPatch1,Length(MultiPalPatch1),Write); WriteProcessMemory(ProcInfo.hProcess,ptr(MultiAddress2),@MultiPatch2,Length(MultiPalPatch2),Write); { Write Patch3 to memory } WriteProcessMemory(ProcInfo.hProcess,ptr(Address3),@Patch3,Length(Patch3),Write); { Write Patch4 to memory } WriteProcessMemory(ProcInfo.hProcess,ptr(Address4),@Patch4,Length(Patch4),Write); { Write Patch5 to memory } WriteProcessMemory(ProcInfo.hProcess,ptr(Address5),@Patch5,Length(Patch5),Write);{ ----------------------------------------------------------------------- } { Resume the thread } ResumeThread(ProcInfo.hThread); CloseHandle(ProcInfo.hProcess); end;end;Thats for delphi using 5 diffrent patches and address's , Ill post asm code to do the exact same thing when i find it, Edited March 29, 2008 by Departure
blaCke Posted March 29, 2008 Posted March 29, 2008 I hope that help you .386 .model flat,stdcall option casemap:none include windows.inc include kernel32.inc include user32.inc includelib kernel32.libincludelib user32.lib .data? StartupInfo STARTUPINFO <>ProcessInfo PROCESS_INFORMATION <>BytesWritten dd ?.data TargetName db "App.exe",0ProcError db "Error starting target process.",0WriteError db "Error writing to target process",0PatchByte db ??h PatchVA dd ??h; <=Virtual address.codestart: invoke CreateProcess,addr TargetName,0,0,0,0,CREATE_SUSPENDED,0,0,addr StartupInfo,addr ProcessInfo .if eax==0 invoke MessageBox,NULL,addr ProcError,NULL,MB_ICONERROR .else invoke WriteProcessMemory,ProcessInfo.hProcess,PatchVA,addr PatchByte,1,addr BytesWritten .if BytesWritten!=1 invoke MessageBox,NULL,addr WriteError,NULL,MB_ICONERROR invoke TerminateProcess,ProcessInfo.hProcess,0 .else invoke ResumeThread,ProcessInfo.hThread .endif .endif invoke ExitProcess,NULLend start
.::God::. Posted March 29, 2008 Author Posted March 29, 2008 Thanks alot guys for all your help. I REALLY REALLY appreciate it. But i still cant find a working example
.::God::. Posted March 29, 2008 Author Posted March 29, 2008 Here try something like this:ProcessInfo PROCESS_INFORMATION <>align dwordpContext CONTEXT <>Patch db EBh, FEhOriginal dd ?VAEntryPoint dd ?VADefWindowProcA dd ?Invoke CreateProcess, _target,0,0,0,0,CREATE_SUSPENDED,0,0,0, offset ProcessInfoInvoke WriteProcessMemory, ProcessInfo.hProcess, VAEntryPoint, offset Patch, 2, 0Invoke ResumeThread, ProcessInfo.hThread.while TRUEInvoke GetThreadContext, ProcessInfo.hThread, offset pContextPush pContext.regEippop eax.break .if eax == VAEntryPoint.endwInvoke SuspendThread, ProcessInfo.hThreadInvoke WriteProcessMemory,ProcessInfo.hProcess, VAEntryPoint, offset Original, 2, 0Invoke WriteProcessMemory, ProcessInfo.hProcess, VADefWindowProcA, offset Patch, 2, 0Invoke ResumeThread, ProcessInfo.hThread.while TRUEInvoke GetThreadContext, ProcessInfo.hThread, offset pContextPush pContext.regEippop eax.break .if eax == VADefWindowProcA.endwInvoke SuspendThread, ProcessInfo.hThreadInvoke WriteProcessMemory,ProcessInfo.hProcess, VADefWindowProcA, offset Original, 2, 0////////////////////////////////////////////////////////////////////////////////////////////////////////Do your work////////////////////////////////////////////////////////////////////////////////////////////////////////Invoke ResumeThread, ProcessInfo.hThreadInvoke ExitProcess, 0Something like that should work fine. Obviously this is not a complete example, you'll have to get original bytes and addresses, also mov pContext.ContextFlags, 1001Fh before GetThreadContext calls, otherwise it wont work.Thx for that, i'll try it out now.
Departure Posted March 29, 2008 Posted March 29, 2008 Whats not working about the examples?? Bothe asm look correct its just a matter of filling in the blanks to suit your app, And the Delphi one is straight from one of my own loaders So its just a matter of changing the Virtual Address's and Bytes, These codes should work fine for you the only other option if you still can get it to work is tell us the Virtual address's and the bytes you want changed and ofcause app path
diablo2oo2 Posted March 30, 2008 Posted March 30, 2008 if WriteProcessMemory fails it could be that the loader is trying to patch writeprotected memory. just use VirtualProtectEx and apply PAGE_EXECUTE_READWRITE flag to the targetmemory.http://phpfi.com/306271?lang=gpasm
KuNgBiM Posted June 8, 2008 Posted June 8, 2008 (edited) ; Use: ml /c /coff loader.asm; link /SUBSYSTEM:WINDOWS loader.obj rsrc.obj; *** Begin of loader - Optimized for MASM32 ***.386.model flat,stdcalloption casemap:noneinclude c:\masm32\include\windows.incinclude c:\masm32\include\kernel32.incinclude c:\masm32\include\user32.incincludelib c:\masm32\lib\kernel32.libincludelib c:\masm32\lib\user32.libDlgProc PROTO :DWORD,:DWORD,:DWORD,:DWORD.dataAppName db 'MemoryPatcher',0msg_run db 'Faild to launch program',0Dh,0Ah,'or CreateProcess function error :P ...',0msg_read db 'ReadProcessMemory error ...',0msg_ver db 'Wrong version :P ...',0msg_cap db 'Memory Patcher error ...',0msg_write db 'WriteProcessMemory error ...',0m_progname db 'example.exe',0; ---- Patch Data ---- m_addr_to_patch1 dd 0040FA77hm_original_bytes1 db 07Ch, 01Ehm_new_bytes1 db 0EBh, 01Ehm_num_of_bytes1 dd 2DlgName db "SPLASH",0TimerID dd 0TimeOutValue dd 3000m_loop_me dd 10000.data?hInstance HINSTANCE ?read_buffer db 512 dup (?)startinfo STARTUPINFO <>pi PROCESS_INFORMATION <>.codestart:invoke GetModuleHandle,NULLmov hInstance,eaxinvoke DialogBoxParam,hInstance,addr DlgName,NULL,addr DlgProc,NULLinvoke GetStartupInfo,addr startinfoinvoke CreateProcess,addr m_progname,NULL,NULL,NULL,FALSE,20h,NULL,NULL,addr startinfo,addr pitest eax,eaxjz _launch_errormov ebx,m_loop_me_the_loop:invoke ReadProcessMemory,dword ptr [pi],m_addr_to_patch1,addr read_buffer,m_num_of_bytes1,0test eax,eaxjz _read_proc_errorlea esi,read_bufferlea edi,m_original_bytes1mov ecx,m_num_of_bytes1repz cmpsbjnz _downjmp _patch_the_mother_down:dec ebxjnz _the_loopjmp _wrong_ver_patch_the_mother:invoke WriteProcessMemory,dword ptr [pi],m_addr_to_patch1,addr m_new_bytes1,m_num_of_bytes1,0test eax,eaxjz _write_proc_errorjmp _exit_launch_error:invoke MessageBox,NULL,addr msg_run,addr msg_cap,MB_ICONSTOP+MB_OKjmp _exit_read_proc_error:invoke MessageBox,NULL,addr msg_read,addr msg_cap,MB_ICONSTOP+MB_OKjmp _exit_wrong_ver:invoke MessageBox,NULL,addr msg_ver,addr msg_cap,MB_ICONSTOP+MB_OKjmp _exit_write_proc_error:invoke MessageBox,NULL,addr msg_write,addr msg_cap,MB_ICONSTOP+MB_OK_exit:invoke CloseHandle,dword ptr [pi]invoke CloseHandle,dword ptr [startinfo]invoke ExitProcess,0DlgProc proc uses esi edi ebx,hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM .IF uMsg==WM_INITDIALOG invoke SetTimer,hWnd,1,TimeOutValue,NULL mov TimerID,eax .ELSEIF uMsg==WM_TIMER invoke KillTimer,hWnd,TimerID invoke SendMessage,hWnd,WM_CLOSE,NULL,NULL .ELSEIF uMsg==WM_CLOSE invoke EndDialog,hWnd,NULL .ELSE mov eax,FALSE ret .ENDIF mov eax,TRUE retDlgProc endpend start.586.model flat,stdcalloption casemap:noneinclude \masm32\include\windows.incinclude \masm32\include\user32.incinclude \masm32\include\kernel32.incincludelib \masm32\lib\user32.libincludelib \masm32\lib\kernel32.lib.dataFileName db "example.exe",0Error db "Process could not started!",0Startup STARTUPINFO <>processinfo PROCESS_INFORMATION <>.data?hInstance HINSTANCE ?ByteBuf dd ?.codestart: invoke GetModuleHandleA, NULL mov hInstance,eax invoke CreateProcess, addr FileName, NULL, NULL, NULL, NULL, CREATE_SUSPENDED,NULL, NULL, addr Startup, addr processinfo .if eax == NULL invoke MessageBox, NULL, addr Error, NULL, MB_ICONEXCLAMATION .else call patch .endif invoke ExitProcess,eaxpatch proc hWnd: DWORDLOCAL tmp: byte _patch macro _pos, _byte mov tmp, _byte invoke WriteProcessMemory, processinfo.hProcess, _pos, addr tmp, 1, ByteBuf invoke ResumeThread, processinfo.hThread endm_patch 00543210h, 090h_patch 00543211h, 090h_patch 00543212h, 090h_patch 00543213h, 090h_patch 00543214h, 090h_patch 00543215h, 090h_patch 00543216h, 090h retpatch endpend startprogram loader;uses Windows;var si : Startupinfo; pi : Process_Information;procedure Patch(Address: Cardinal; PatchedBytes: Array Of Byte; OrigBytes: Array Of Byte);var NBW: Cardinal; Old: byte;begin ReadProcessMemory(pi.hProcess, Pointer(Address), @Old, 1, NBW); if OrigBytes[0] = Old then begin WriteProcessMemory(pi.hProcess, Pointer(Address), @PatchedBytes[0], Length(PatchedBytes), NBW); ResumeThread(pi.hThread); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); end else begin Messagebox(0,pchar('Bytes not found...'),pchar('Error'),mb_iconinformation); TerminateProcess(pi.hProcess,0); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); end;end;begin if CreateProcess(nil,'example.exe',nil,nil,FALSE, Create_Suspended,nil,nil,si,pi) = true then begin Patch($00543210, [$EB, $10], [$75, $10]); Patch($00555555, [$C3, $90], [$55, $8B]); end;end. Edited June 8, 2008 by KuNgBiM
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