Log in

View Full Version : Process patching yet again


crUsAdEr
April 17th, 2002, 03:02
Yep, i know i know.. a search for loader / process patch gives mt like 250 threads to browse through... but i just have one more question at the moment...

I have been staring at R!sc 's process patcher's source code... as well as disassmble the loader created with RPP... there is one thing i am not sure...

R!sc create the process (suspended), then start checking the VA to be patched for the same bytes pattern as the original bytes given, once found patch will be performed... the question is what is the duration between each read process memory, i do not see any kind of timer... does R!sc just let the child process runs and then continuously read and read the process memory?

Thanx,

Kayaker
April 17th, 2002, 07:17
Hi binh81,

It looks like R!sc uses a counter, as opposed to a timer per se. This is the "T" value in the script, or if you use Nchanta's GUI, the number of times to try to patch before giving up.

From the source code this appears to be the p_timeout value, which is encoded at address 406000 in the rppdata section:

Code:

mov esi, 406000h
mov eax,[esi] ; get process timer from rppdata section
mov [p_timeout],eax


A counter (Ptimer) is used to compare the number of times the ReadProcessMemory loop has run, and since the whole process takes a certain amount of time, this is where the 'effective' timer comes from I gather.

Code:

waitagain:
add dword ptr [Ptimer],01
push eax
mov eax, dword ptr [p_timeout]
cmp dword ptr [Ptimer],eax
pop eax
jz VersionERR ; whoops, xxxx checks failed, quitting
pushad
Check_Data:
push 0 ; BytesRead
push ebx ; Length
push offset CSiR_RPBuffer ; Destination (to read them to)
push ecx ; Source
push dword ptr [CSiR_ProcessInfo] ; Process whose memory we are to read
call ReadProcessMemory
...
mov ecx, ebx
rep cmpsb ; compare read bytes against check bytes
popad
jnz waitagain ; jump if not equal to check again
; (cause a few milliseconds have passed, and they may? be there)


Personally I didn't have much luck with the process patcher, though it is the first time I've tried it. ReadProcessMemory returned *nothing*, so there were no patch bytes to compare. The process (notepad or packed notepad) seemed to be created OK, but ReadProcessMemory couldn't read anything from it (though it didn't return an error).

Plus, unless I specifically forced ResumeThread to be called by changing the following jump, the whole process just hung in memory.
Code:

cmp dword ptr [esi-4],0
jz resumethefucker ; check see if process will be resumed now or later

startpatch:
...


Running it on Win98SE. Kinda surprised it gave me problems actually.

Kayaker

crUsAdEr
April 17th, 2002, 12:07
Hi Kayaker,

Thanx for the detailed analysis... so that means R!sc just keep checking the running process while the other process is running? I suppose it is based on the time slice of each process for the CPU cycle? That is where the few milli seconds come from?

R!sc's Process Patcher seems to do OK on my win2k SP2 but i only tested it once... kayaker, if u tested it with AsProtect then i think it has some anti loader feature hence it wont work...

Thanx a lot, kayaker,
Binh

P.S : Lord Rhesus's VBLoader use the exact same algorithm....

crUsAdEr
April 18th, 2002, 20:08
Hi folks, me yet again!!

Yep, i am having a slight problem... i want to load my own dll into the space of a child process.. what i want to do is replace a API call to a call to my own dll... so i need to change that value at IAT thunk.. i use CreatProcess with _CREATE_SUSPENDED... try to write to the overwrite the IAT entry.. but the problem is that i realise IAT is NOT initialised yet.. so IAT is not pointing to API address but instead the API ascii in the child process... so i cant patch it yet cos if i do the process wont run...

So what i need to do is patch IAT antry after it has been initialised but before the process start executing... So how should I do that? I dont want to patch my kernel API yet just in case my code is crap and it mess up my windoze....

So could someone please tell me how i should go about doing this?

Thanx

Kayaker
April 18th, 2002, 23:58
Hi binh81

As you said, you need to intercept the process a little later on, after the PE loader has done its business and the First Thunk has been initialized with the real addresses of the APIs and the PE file is ready to run.

The method I'm familiar with for injecting a dll into another process' address space is from Iczelion's IczDump. After mapping the file into memory you parse the PE header and get the OEP, then you create the process suspended and "save" a certain number of bytes from the start of the process (at the OEP) with ReadProcessMemory. These will be overwritten by your injection code, which is allowed to run, then replaced.

Then you prepare your injection code, which is a standard LoadLibrary routine to load a (your own) dll. Since the target process may not import LoadLibraryA you'll need to get its address first and hardcode the value into your injection snippet. WriteProcessMemory writes your injection code over the original and is allowed to run with a CreateEvent object. I think you can also use SetThreadContext and ResumeThread to do this.

Once your dll is loaded it replaces the original bytes and jumps to the OEP directly. It's at this point in your dll, just before returning control to the program, that I thought you could manipulate the IAT. You can get the start of the IAT from the PE header, then maybe "walk" the export directory for each thunk address until you find the API name you're trying to hook, then change that address to your own. I've got a WalkExportDirectory ASM module written up that will return the API Name and DLL Name for any thunk address inputted if that helps the cause...

See if you can suss out how Iczdump does it, it should be fairly straightforward careful reversing of the loader procedure. The 'injected' code he uses looks like just random bytes until you actually see it disassembled in operation.

Also, I figure you've already seen the new 'API hooking revealed' article I posted a link to recently. You may find some ideas in there. It seems to favor using CreateRemoteThread for dll injection in NT and Win2K.

Cheers,
Kayaker

crUsAdEr
April 19th, 2002, 10:27
Yep, should have thought of that..

Thanx kayaker... simply freeze the process at Entry point instead.. then IAT is already loaded...

thanx a lot..

Fake51
April 19th, 2002, 17:34
I had to patch a program inline a wee while ago, and the patch had to work across different windows platforms. I started out hoping that I could inject my own dll by just changing the iat, but as you found out, it was no good. I then tried some of the older essays on the fortress and found one by Stone on runtime patching. The two first approaches mentioned I was already familiar with, and didn't bother trying to implement in this case (as it would have been a problem trying to figure out when to patch - program is wrapped). The third approach was on windows hooks, but wasn't explained. It wasn't too much bother to figure out though, and it gave some nice possibilities.
The nice thing was that the code I wanted to patch was run AFTER the program created it's first window. So it was possible to install a hook into the windows message chain. The beauty of the thing is, that if you place your hook in a dll, and either let it be thread specific or global, it will be notified when the window is created .... and the thread will be located in memory ready for patching. Furthermore, your dll will have the rights of the program, thus you can go right ahead and use virtualprotectex, then writeprocessmemory (or use a mov dword ptr [xxxxx],exx, since you have the same rights as the program). After the patching is done, it's just a matter of unhooking.
The beauty of hooking the message chain is that it's easy, and there are some nice possibilities: you can hook both win-proc messages and debug messages. Plus, it works the same on win98, win2k, winxp ... no need to figure out what os before you start running.

Just thought I'd chip in.
Fake

evaluator
April 20th, 2002, 09:32
Hello, binh81!

Want say one TERRIBLE newz

Using DZA-patcher's [GREAT] loader engine, is possible patch any (and aspr also)
protection scheme.
Simple in aspr error happens because after aspr checks CRC.

So I found TERRIBLE easy way {trick}, and loader patches code after CRC check!
Without any timer & etc............

So last ASPR's "legend" defeated.

WE WILL,

Kayaker
April 20th, 2002, 19:25
Hi

I dug up the Message hook doc and source by Stone that Fake51 talked about. The explanation in the original tut in the old Fravia database (stone1.htm in the Academy300 section) is missing, but Stone did include it at his website before it closed down. I have a copy of the entire Stone's website, which is very interesting reading, and actually uploaded the 1.2Mb file to the REKML site a long time ago. You can probably get it there (REKML still active??), or it might have been included in the RCE CD (don't know).

In any case, for posterity here it is.

Kayaker

---------------------------------------------------------------------------
In Memory Patching - The MessageHook Approach
by Stone

I'll skip relatively lightly over the in-depth technical issues of this method.
It is simply far beyond this text to go into it. Maybe someday I'll write a
book or something sorry..

The above method has it's advantages - and disadvantages. It's cumbersome.
Indeed in many instances access to foreign addressing spaces can be gained
easier. I will now examine one such method. The method was first described
in MSJ 1994. I first noticed the potency of this method examing Grudge's crack
for SubSpace. My sourcecodes and approach as such bares many resemblances with
Grudge's initial work.

Most likely you've all encountered Windows Messageing system at one point or
another. Breakpoints on "BMSG", HWND command in Winice is indeed breakpoints
on messages and list possible recievers of messages. The whole idea behind
messages goes back to the fact that we have a multitasking operating system.
Several tasks needs to share equipment that can only be used by one at the time.
The obvious example is the mouse - the user will have only ONE mouse total, not
one for each thread. Another is the keyboard, keyboard input is often ment for
only one of the running threads. A total breakdown of the windows messageing
and windowing system is far far beyound the scope of this small text. It'll
suffice to say that any window made by any thread in any process is controlled
thru messages from the Windows operating system.

Again we'll exploit that Windows is an overbloated operating system - or well
as I would rather put it - a very potent equipped OS. The feature we'll be
exploiting here is that of a Hook in the message system. For many reasons
Microsoft decieded that even at ring 3 people should be able to intercept
messages send to windows. Because they wanted this hook to be usuable for
Computer Based Training they decieded that a hook would be no good if it did
not have direct access to the addressing space of the process belonging to the
thread it captured a message for. So they decieded that a MessageHookHandling
procedure should be loaded into any process in which it captured a message.
Further developers must've felt generous the day they designed this. They
allowed a hook not just to one process - but to all!

Let's get a bit more technical on this. The API that installs the hook is:
User32!SetWindowsHookExA

The first problem about using this API to hook windows messages globally is
the way it gain access to the address space of the thread which it intercepted
a message to. To get real deep on this issue is again far beyound the scope
of this text, but it has to do with how modules is mapped in pages thru out
the various memory contexts (Process addressing spaces).
The result is that you cannot have the hook within the EXE file that installs
the hook - rather you need to have it in a DLL.

In other words we start out by loading the DLL in which we have our hook, then
find the address of our hook procedure in it and feed this to SetWindowsHookExA.


The next problem we encounter is that of designing a messagehandling system.
Since a LOT of messages is send out to windows system wide all the time it's
important that we design our hook to be relatively fast or we'll be slowing the
system. The easist way of doing this is only acting upon messages of a specific
type. Choosing type depends on how you wish to time your patch. You can in
this way time it to hit on keyboard activity in a window, mouse activity,
windows being put to background and so on and so forth.

I've choosen the real simple hook type intended for ComputerBasedTraining. This
hooks a large number of messages related to windows giving us plenty of things
to act on without intercepting everything. Further in the hook procedure I
test weather the message send was one that is supposed to create a window.
This allows me to patch right after the "main" window of the program is created.
Without intercepting too much and even when intercepting I only run a few bytes
of my code unless ofcause it happens that the program is creating a window.
Obviously I might end up patching more than since this message type can be
send many times. Other strategies could be hooking the keyboard, all messages
etc. I very much believe that which type of hook and the exact design of your
hook-handler is an issue that should be solved in relation to the specific
problem you're dealing with. For instance in training hooking the keyboard
and only acting on specific keys would be a good idea instead of acting on
the window.

Mammon/HCU suggest a boolean variable to see if you already applied a patch.
This can be a very good idea. Even better would be if you shut down your
hook-installing process (program) and the hook along with it after you've
patched. You should however be aware that this method has a caveat if your user
deciedes to run multiple versions of the program you patched or if you're
patching kernel32.dll in memory since this DLL might need to be patched more
than once because an unpatched version might later on be mapped into your
target's addressing space. Thanks to Mammon/HCU for a beneficial suggestion.

The next problem is that we need to hinder that we patch all processes. Again
I abuse the concept of modules. By getting the current module filename and
compareing it to the filename of the file we desire to patch I can identify
weather this message was send to the target or to another program windows.

And the last problem is ofcause that we cannot keep messages from the target's
windows and expect it to perform like it's supposed to. What we do is that we
chain other possible hooks using the neatly provided API:
user32!CallNextHookEx

One final things is worth noting Exiting the process who "owns" the hook will
destroy it - in other words we cannot shut down until we're sure we've patched
the program and we cannot shut down if need multiple patches (as patching
e.g. kernel32.dll (which is a bad idea anyway) would require. The good thing
about it is that we can simply call ExitProcess when we're done and windows
will take down the hook for us with no further adue... Pretty clever MS!

Since we in the hook-procedure have direct access to the addressing space
of the target process we wouldn't need to use WriteProcessMemory, however
it's a very good idea to do so. First and foremost WPM as described earlier
overrides pageprotection. Second and also important - there is a difference
in how pages in a process is handled between Windows 95 and Windows NT. If
you patch a program's pages in Win NT (if it's not shared) it'll be copied
and then the copy will be patched - thus the patch will not affect other
processes utillizing the same module. In windows 95 this is not so. However
WriteProcessMemory in Windows 95 has build in this mechanism ensuring that
if you use WriteProcessMemory you'll not suffer differences between NT and
95. (This is not true if you patch above the 2g limit - which I btw cannot
see why you'd do)

Here at the end I'll shortly describe the caveats of this method. It requires
a window. Without a window in the target process you can't do didly with this
method. However you can use this method to inject a DLL into the address space
after the window has disappeared and then patch the IAT to make a API-hook of
it like in the Debug-approach section.

Sourcecode - stnmsgh.zip
-------------------------------------------------------------------------

crUsAdEr
April 21st, 2002, 14:21
Hmm...

Thanx Kayaker... Nice reading....

It also brought back to my intention that I was looking for the RCE CD sometimes ago when i found a long thread about it... Cant find it anywhere though... If there a way for newbie/latecomer like me to obtain it somewhere?

Hope this is not classified as warez request :>???

Thanx

Fake51
April 23rd, 2002, 15:40
Nice, Kayaker. Don't think my (old) copy holds that info, or maybe I'm just going blind ....
For info on how to go about implementing hooks, look to iczelion. As always, one can find info and code there.

Blue skies
Fake

crUsAdEr
April 23rd, 2002, 17:32
Yep.. thanx Fake51,

me reading over there now :>

cheers,

P.S : doesnt seem as hard as it sound :>... but maybe cos i have not really implement it yet....