Basically, I cannot find which process is being written to when WriteProcessMemory is being called. Currently I'm Setting Breakpoints on WriteProcessMemory and OpenProcess. However, the process handle being passed to WriteProcessMemory is different from that obtained from OpenProcess, so it appears that the process handle is being obtained in another way. Is there something I'm missing out on? Should I add more breakpoints on other functions?
3 Answers
It is also easy using x64dbg. When you break on the WriteProcessMemory
the handle will be at [esp+0x4]
in the memory.
After you write down the handle (in this case 0xDC) you may go to the Handles
tab in the x64dbg main window, then Right click -> Refresh
. All the handles associated with your debugged process will be listed. Now you need to find the corresponding handle and that's it.
As you can see, in my case the WriteProcessMemory
was writing to a process with PID 0x7A30.
If you don't use a debugger that lets you list handles (unlikely) you can use external tool like Process Explorer, which also has the ability to list all process associated handles.
which debugger are you using ?
most debuggers will decipher the handle on the spot
that is you can find out the handle info when you have broken on the WriteProcessMemory() Call itself
here is how you can do it with windbg
i am debugging ollydbg and olllydbg ais debugging calc.exe
ollydbg is setting a breakpoint in calc.exe (uses WriteProcessMemory() )
0:000> bl
0 e Disable Clear 752444cf 0001 (0001) 0:**** KERNELBASE!WriteProcessMemory
0:000> .lastevent
Last event: c90.e10: Hit breakpoint 0
0:000> kb1
# ChildEBP RetAddr Args to Child
00 0012bd44 00457929 0000014c 009c2000 02973020 KERNELBASE!WriteProcessMemory
0:000> !handle 14c f
Handle 14c
Type Process
Attributes 0
GrantedAccess 0x1fffff:
Delete,ReadControl,xxxx,SetPort
HandleCount 4
PointerCount 10
Name <none>
Object Specific Information
Process Id 3336
Parent Process 3216
Base Priority 8
0:000> dx Debugger.Utility.Control.ExecuteCommand(".tlist").Where(a=>a.Contains("3336")==true)
Debugger.Utility.Control.ExecuteCommand(".tlist").Where(a=>a.Contains("3336")==true)
[0x30] : 0n3336 calc.exe
0:000> dx Debugger.Utility.Control.ExecuteCommand(".tlist").Where(a=>a.Contains("3216")==true)
Debugger.Utility.Control.ExecuteCommand(".tlist").Where(a=>a.Contains("3216")==true)
[0x2f] : 0n3216 ollydbg.exe
Many programs, especially malware, start a suspended child process (CreateProcess
variants), overwrite its code with their own (WriteProcessMemory
with or without VirtualAllocEx
) and resume the main thread (ResumeThread
).
Also look for ReadProcessMemory
, it is possible that the call to OpenProcess
that you see is actually the same process reading from its own pages and the WriteProcessMemory
is writing to the newly created process, with its different handle.
Note that these functions also have low-level variants (ZwCreateThread
etc.)