flat assembler
Message board for the users of flat assembler.

Index > Windows > PE Import Section

Author
Thread Post new topic Reply to topic
Marikallees



Joined: 21 Apr 2006
Posts: 4
Marikallees
Okay, I'm trying to figure out how a PE is structured. In particular, what the import macros that FASM provides really do. Smile The FASM Win32 source shows this:
Code:
section '.idata' import data readable writeable

  dd 0,0,0,rva kernel_name,rva kernel_table
  dd 0,0,0,0,0

  kernel_table:
    ExitProcess dd rva _ExitProcess
    CreateFile dd rva _CreateFileA
    ReadFile dd rva _ReadFile
    WriteFile dd rva _WriteFile
    CloseHandle dd rva _CloseHandle
    SetFilePointer dd rva _SetFilePointer
    GetCommandLine dd rva _GetCommandLineA
    GetEnvironmentVariable dd rva _GetEnvironmentVariable
    GetStdHandle dd rva _GetStdHandle
    VirtualAlloc dd rva _VirtualAlloc
    GetTickCount dd rva _GetTickCount
    GetSystemTime dd rva _GetSystemTime
    GlobalMemoryStatus dd rva _GlobalMemoryStatus
    dd 0

  kernel_name db 'KERNEL32.DLL',0

  _ExitProcess dw 0
    db 'ExitProcess',0
  _CreateFileA dw 0
    db 'CreateFileA',0
  _ReadFile dw 0
    db 'ReadFile',0
  _WriteFile dw 0
    db 'WriteFile',0
  _CloseHandle dw 0
    db 'CloseHandle',0
  _SetFilePointer dw 0
    db 'SetFilePointer',0
  _GetCommandLineA dw 0
    db 'GetCommandLineA',0
  _GetEnvironmentVariable dw 0
    db 'GetEnvironmentVariableA',0
  _GetStdHandle dw 0
    db 'GetStdHandle',0
  _VirtualAlloc dw 0
    db 'VirtualAlloc',0
  _GetTickCount dw 0
    db 'GetTickCount',0
  _GetSystemTime dw 0
    db 'GetSystemTime',0
  _GlobalMemoryStatus dw 0
    db 'GlobalMemoryStatus',0
    

My particular interest is here:
Code:
  dd 0,0,0,rva kernel_name,rva kernel_table
  dd 0,0,0,0,0
    

I believe that the first three initializations are for the import flags, time/date stamp, and minor/major version as described in wotsit's portable executable description. The next is the ASCIIZ RVA name, defined as kernel_name. That's simple. Then kernel_table defines the import lookup table, also simple.

Now for the problem. The PE specification also talks about a sixth field, the import address table. But FASM's source only uses five fields and I've identified them all. There doesn't seem to be an IAT, the IAT doesn't seem to be optional, and a null field isn't accepted. Am I simply reading the specification wrong?

Thanks!
Post 23 May 2006, 14:33
View user's profile Send private message Reply with quote
okasvi



Joined: 18 Aug 2005
Posts: 382
Location: Finland
okasvi
This is what I use and it has always worked. |:
If you count members of struct inside union separately you get 6 members
Code:
struct IMAGE_IMPORT_DESCRIPTOR
        union
                Characteristics         rd 1
                OriginalFirstThunk      rd 1
        ends
        TimeDateStamp           rd 1
        ForwarderChain          rd 1
        Name1                   rd 1
        FirstThunk              rd 1
ends
    
Post 23 May 2006, 23:00
View user's profile Send private message MSN Messenger Reply with quote
KRA



Joined: 14 Jun 2005
Posts: 24
KRA
since OriginalFirstThunk and Characteristics are defined in a union they share the name memory location thus you only have five members.
Post 24 May 2006, 05:42
View user's profile Send private message Reply with quote
Quantum



Joined: 24 Jun 2005
Posts: 122
Quantum
The first member should point to another lookup table (identical to kernel_table). And there's another minor bug: every pointee referenced from this table should be aligned on an even address.

Code:
data import
        dd RVA kernel32_lookup,0,0,RVA kernel32_name,RVA kernel32_table
dd 0,0,0,0,0
end data

kernel32_table:
        ExitProcess dd RVA _ExitProcess
        dd 0

; This is the missing table:
kernel32_lookup:
        dd RVA _ExitProcess
        dd 0

kernel32_name db 'KERNEL32.DLL',0
align 2 ; <- alignment is required!
_ExitProcess dw 0
        db 'ExitProcess',0    
Post 24 May 2006, 14:49
View user's profile Send private message Reply with quote
Marikallees



Joined: 21 Apr 2006
Posts: 4
Marikallees
Quote:
The first member should point to another lookup table (identical to kernel_table).

Does a unique table need to be defined identically, or can the same table be used?
Code:
dd rva kernel_table,0,0,rva kernel_name,rva kernel_table
    

I don't see why 0 is an accepted value when an RVA is expected. Is 0 a valid RVA? It seems like, if the first field is 0, the last field is being used as the lookup table and at binding both the first and last fields refer to the same table.
Quote:
align 2 ; <- alignment is required!

What kind of problems would I expect if it's not aligned? Also, my PE specification (using a different one now, from Microsoft) doesn't mention alignment for the DLL name field. It talks about padding for the hint/name table entries. So wouldn't the fixed code look more like this?
Code:
section '.idata' import data readable writeable 

  dd rva kernel_lookup,0,0,rva kernel_name,rva kernel_table 
  dd 0,0,0,0,0 

  kernel_table: 
    ExitProcess dd rva _ExitProcess 
    CreateFile dd rva _CreateFileA 
    ...
    dd 0

  kernel_lookup:
    dd rva _ExitProcess
    dd rva _CreateFileA
    ...
    dd 0

  kernel_name db 'KERNEL32.DLL',0 

  _ExitProcess dw 0 
    db 'ExitProcess',0
  align 2
  _CreateFileA dw 0 
    db 'CreateFileA',0 
  align 2
  ...
    

One more thing. Would the last entry in the list need to be aligned as well? Smile I haven't worked with code alignment yet, does align 2 mean that the next code is aligned to an even boundary as your code suggests, or does it simply pad with 2 NOP instructions? I'm pretty sure it's the first one, but I need to make sure before I break something. Smile
Post 24 May 2006, 15:32
View user's profile Send private message Reply with quote
Quantum



Joined: 24 Jun 2005
Posts: 122
Quantum
Quote:

Does a unique table need to be defined identically, or can the same table be used?

I'm not sure about this. I guess it won't work in some special cases (maybe DLL binding...) MS linker generates both tables for a reason.

Quote:

I don't see why 0 is an accepted value when an RVA is expected. Is 0 a valid RVA?

Usually a 0 RVA means no entry. This applies to relocation tables, resources, etc.

Quote:

So wouldn't the fixed code look more like this?

And who's gonna align _ExitProcess, huh?

The DLL name is aligned, because it follows an array of doubleword values (the lookup tables).

Quote:

What kind of problems would I expect if it's not aligned?

No problems at all, but it's a bit faster when aligned. It's always better to follow the rules, IMHO.

Quote:

does align 2 mean that the next code is aligned to an even boundary

Yes
Post 24 May 2006, 21:46
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar.

Powered by rwasa.