#1
|
|||
|
|||
Import Rebuilding Without Import Table
I'm trying unpack a protected game. So far I have removed all dummy code from the file, resolved all INT calls to its kernel driver an replaced the code and patched all the imports so that they jump right to the correct API without going through the protection's code.
A normal API call goes like this "CALL DWORD PTR [????????]" (FF 15 ?? ?? ?? ??). However, the calls in this game go like "CALL ????????" (E8 ?? ?? ?? ??) and either before or after this call (6 byte<->5 byte call) there is a one byte dummy instruction like "nop" "cld" or like that. The the "E8 call" points to a direct jump to the API. So there is no problem to resolve the API. The problem is that the game has no import table anywhere (not on disc or in memory or encrypted or unfilled) but just this kind of calls. So I'm a bit lost how and where I should rebuild the import table. Leaving it like now is not possible since the DLLs are loaded to a different address every time and the system APIs have different addresses on each OS. |
#2
|
|||
|
|||
The programs that use some APIs, have import table that points to the name & module of needed APIs .
At the runtime, the loader (Operating system) loads appropriate modules (such as Kernel32, User32 & GUI32) and fills the entries of this table with the current address of APIs in the memory. In the packed or encrypted programs, the unpacker routine that runs at the start of the program, performs this operation. This routine first loads the module with LoadLibray() API and then finds the address of desired APIs by calling GetProcAddress(). If you can not remove this unpacking routine, you should use other hooking techniques such as DLL injection. |
#3
|
|||
|
|||
Set a breakpoint on LoadLibrary and GetProcAddress. When those are called, figure out where they were called from. Since there is no import table it's probably enumerating the loaded modules, storing it in a variable somewhere, and then calling them directly (rather than through the import table). It's pretty easy to manually simulate GetProcAddres, but LoadLibrary is a bit more complicated, so at the very least it should LoadLibrary(Ex) should will likely get a hit.
|
#4
|
|||
|
|||
@hajir:
I think "Kerlingen" knows about what you write since he says that he has patched the imports to point directly to the API. As far as I understand him, he has this kind of code: Code:
(...) call some_label ; E8 call, not FF15 call (...) some_label: jmp dllname!exportname ; "E9" relative jump @kerlingen: Have you tried to find code like this Code:
mov esi, [offset iat+somevalue] call esi ;or jmp dword ptr [xxxxxxxx] ; FF25 jump |
#5
|
||||
|
||||
Quote:
If the IAT is not in your prog, you only would see GetProcAddress/loadlibrary procedures and a call to a memory address. AFAIK there's only two methods to call API funcs: 1.-Imports by your compiler. 2.-Loadlibrary/GetProcAddress |
#6
|
|||
|
|||
Quote:
this. Or to learn about IAT stuff do it manually One thing you can do is the following: build a table with all API addresses the e8-calls refer to, then patch all e8-calls back to ff15(address of the api entry in your table) and let ImportRec rebuild a new IAT. |
#7
|
|||
|
|||
Sorry for replying so late, but my user status allows me only to post one message a day. And thank you to everybody who replied to me.
But I'm afarid either I explained my problem wrong or you didn't understand what I wanted to know. I try to say it more clear this time. I am aware how manual and automatic import rebuilding works in normal cases. As you say, in packed or encrypted programs the IAT is not filled by the operating system, but by the loader. Normally you have 3 ways of calling an API: Code:
; ; 1. way ; Call DWORD PTR [IATEntry] ; ; ; ; 2. way ; Call __imp__IATEntry ; __imp__IATEntry: Jmp DWORD PTR [IATEntry] ; ; ; ; 3. way ; Mov Reg32, [IATEntry] Call Reg32 ; @tr1stan: Your idea sounds logical. I will try it as soon as I am back at my PC. Thanks. |
#8
|
|||
|
|||
You may use ImportReconstructor to rebuild import table, but some packers
like asprotect take some api's like GetCurrentThread - and move those value to theirs memory - that inport reconstructor can't find any api on current offset, other api is GetCommandLineA - those apis you must rebuild manually - put only the corrent offet in imprect |
#9
|
|||
|
|||
I did unpacking app like your case.
my case was Starforce. (3 years ago.. hugh~~) SF used emulating of Kernel,GDI,User process. first I dumped code section, & alpha.dll (It emulate imported function) and I checked all opcode pointed on alpha.dll in code section. like call alpha.xxxx jmp alpha.xxxx mov reg32,alpha.xxxx I gathering all opcode address & referece address point. and I made new IAT by gathered information. gathering is so Hard or not. If you want find Making Import table, Check hxxp://win32asm.cjb.net <Iczelion's Win32 Assembly Homepage> There good information about PE File format. |
#10
|
|||
|
|||
@hinte:
In the current state I have not yet an IAT, so there is no way to use ImportREC. I am aware of the emulating problem, so far I have found 18 emulated functions and still need to find out what many of them do. @OrionOnion: I'm not trying to unpack Starforce, but the protection uses very similar methods like you described. There is no external DLL, but the base address of the emulation code is in the protector's PE section. From there the code leads to some manually allocated memory handling all the emulation and the API calls. Currently it looks like only KERNEL32 is emulated, but I haven't identified all calls yet. @omidgl: I don't want to seem unthankful or agressive to you, but I already wrote two times that there is no IAT (=it does not exist anywhere) and I'm writing it now again. I already removed all of the protection's code from the import handling, so there is no need to use API spying since I know all APIs expect some emulated APIs (which can't be found by spying, since they never execute any kernel code), my problem is only how to build the IAT out of nothing with only relative calls and jumps in the code. |
#11
|
|||
|
|||
Question
the discussion was very great but I don't know what is IAT .
and thank you for that link to W32Dasm PE information. |
#12
|
|||
|
|||
I finally managed to rebuild the import table and get rid of all the protection's code. I was able to do it by manually building an IAT from the relative calls and replacing them with normal "FF 15" calls. I also resolved the 18 emulated functions. Thank you again to everybody who helped me here.
The strange thing is now that I have one real and one emulated "SetLastError" API call. Does anybody know if there is an alternative name for this API? I had two more double entries, but it turned out that the same function was exported under two different names. Now it's only optimizing the PE structure and playing hide and seek with the programmers so that I don't die after 10 seconds in the game while everything else works fine. |
Thread Tools | |
Display Modes | |
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Add imports to DLL import table | jonwil | General Discussion | 5 | 09-07-2020 16:47 |
How to shuffle names in the PE import table? | Newbie_Cracker | General Discussion | 5 | 08-25-2019 03:59 |
Reliable PE Library or DLL for Adding Functions to Import Table | omidgl | General Discussion | 3 | 06-28-2008 09:53 |
Can`t restore import table | thechatter | General Discussion | 9 | 11-14-2003 21:01 |
Changing Import Table?? | magic | General Discussion | 3 | 09-14-2003 01:59 |