Exetools  

Go Back   Exetools > General > General Discussion

Notices

Reply
 
Thread Tools Display Modes
  #1  
Old 01-10-2005, 23:44
Kerlingen
 
Posts: n/a
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.
Reply With Quote
  #2  
Old 01-11-2005, 16:11
hajir
 
Posts: n/a
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.
Reply With Quote
  #3  
Old 01-11-2005, 18:34
dmownz
 
Posts: n/a
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.
Reply With Quote
  #4  
Old 01-11-2005, 20:12
MarkusO
 
Posts: n/a
@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
So his problem is that normally there is a call or jump to an address of the import table but here it isn't and he doesn't find the IAT in merory or there is even no IAT, so he has no table of entries like you called it.

@kerlingen:
Have you tried to find code like this
Code:
mov     esi, [offset iat+somevalue]
call    esi

;or

jmp     dword ptr [xxxxxxxx]     ; FF25 jump
If your code is written in high-level language (which I think nearly all games are) you should find my code somewhere.
Reply With Quote
  #5  
Old 01-11-2005, 22:02
taos's Avatar
taos taos is offline
The Art Of Silence
 
Join Date: Aug 2004
Location: In front of my screen
Posts: 580
Rept. Given: 65
Rept. Rcvd 54 Times in 19 Posts
Thanks Given: 69
Thanks Rcvd at 133 Times in 36 Posts
taos Reputation: 54
Quote:
Originally Posted by Kerlingen
the "E8 call" points to a direct jump to the API. So there is no problem to resolve the API.
If you can see the direct jump to the API is because there's imports.
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
Reply With Quote
  #6  
Old 01-11-2005, 22:16
tr1stan
 
Posts: n/a
Quote:
Originally Posted by Kerlingen
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.
You have to rebuild the IAT from scratch, ImportRec. should help you with
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.
Reply With Quote
  #7  
Old 01-12-2005, 03:58
Kerlingen
 
Posts: n/a
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
;
At this point is my problem: There is no IAT. It's not that I wouldn't be able to find it, it's just not present. All APIs are called by relative calls and jumps. Even the "3. way" is present in the code, but Reg32 is not loaded from a memory address, its just "Mov Reg32, Value". It's all hardcoded into the packed code, not replaced by the loader at execution time. I already passed by most of the protection, so that the destination of the relative jumps and calls is a jump to the API. My Problem now is that I don't know where or how I should build an import table. Using Imprec is simply not possible since there is no IAT present.

@tr1stan:
Your idea sounds logical. I will try it as soon as I am back at my PC. Thanks.
Reply With Quote
  #8  
Old 01-12-2005, 07:21
hinte
 
Posts: n/a
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
Reply With Quote
  #9  
Old 01-12-2005, 08:52
OrionOnion
 
Posts: n/a
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.
Reply With Quote
  #10  
Old 01-12-2005, 15:57
Kerlingen
 
Posts: n/a
@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.
Reply With Quote
  #11  
Old 01-12-2005, 17:13
oVERfLOW oVERfLOW is offline
Family
 
Join Date: Jan 2005
Location: Tehran
Posts: 117
Rept. Given: 127
Rept. Rcvd 42 Times in 19 Posts
Thanks Given: 1
Thanks Rcvd at 5 Times in 5 Posts
oVERfLOW Reputation: 42
Question Question

the discussion was very great but I don't know what is IAT .

and thank you for that link to W32Dasm PE information.
Reply With Quote
  #12  
Old 01-13-2005, 10:24
Kerlingen
 
Posts: n/a
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.
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


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


All times are GMT +8. The time now is 17:03.


Always Your Best Friend: Aaron, JMI, ahmadmansoor, ZeNiX, chessgod101
( 1998 - 2024 )