Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to run a PE image without linking kernel32.dll and ntdll.dll

I tried to write a peloader. I first load the executable image and all it's dependent dlls(include kernel32.dll and ntdll.dll) into memory, process all import address table, rewrite all data which need relocation.

Then I call all image's EntryPoint in order. I get the return code 0 from ntdll.dll's EntryPoint, but kernel32.dll returns 0xC0000000. When I tried to call the executable image's EntryPoint, the program crashed.

I know the windows system already load ntdll.dll and kernel32.dll into process memory when the process is created. My question is how can I load another copy of ntdll.dll and kernel32.dll into memory, and link my module to the copy ones.

I make an experiment: 1. copy ntdll.dll -> a.dll

  1. copy kernel32.dll -> b.dll
  2. modify PE image file b.dll to make it not depends on ntdll.dll but a.dll
  3. write a simple program a.exe, and modify the PE image file a.exe to make it not depends on kernel32.dll but b.dll
  4. run a.exe, and the program crashed

Is it possible to make a.exe run correctly?

It's my first question on stack overflow, sorry for my poor english. Thanks.

like image 549
cnzjnblxj Avatar asked Sep 20 '11 07:09

cnzjnblxj


1 Answers

I don't think you can do this. The kernel32.dll and ntdll.dll, AFAIK are not relocatable. That is, MS removed the relocation information from them, because, as they are already loaded in every process, their assigned addresses are always available, by design.

So, if you try to load them into a different address, well, they'll crash. You could theoretically try to rebuild the relocation information for them... but I wouldn't bet on it.

My question in turn is: why cannot you use the preloaded kernel32/ntdll? Why do you feel that you need private copies? As I see it, you should consider them the system API, and so leave them alone.

like image 200
rodrigo Avatar answered Sep 28 '22 12:09

rodrigo