http://www.codeproject.com/useritems/inject2it.asp
http://www.ntcore.com/index.php
Injective Code inside Import Table
DWORD Signature;
IMAGE_FILE_HEADER FileHeader;
IMAGE_OPTIONAL_HEADER OptionalHeader ;
} IMAGE_NT_HEADERS, * PIMAGE_NT_HEADERS;
DWORD it_voffset = pimage_nt_headers -> OptionalHeader.
DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
PIMAGE_NT_HEADERS pimage_nt_headers = (PIMAGE_NT_HEADERS)
(pImageBase + pimage_dos_header -> e_lfanew);
DWORD it_voffset = pimage_nt_headers -> OptionalHeader.
DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
How to get pImageBase?
DWORD OriginalFirstThunk;
DWORD TimeDateStamp;
DWORD ForwarderChain;
DWORD Name;
DWORD FirstThunk;
} IMAGE_IMPORT_DESCRIPTOR, * PIMAGE_IMPORT_DESCRIPTOR;
WORD Hint;
BYTE Name[1];
} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;
typedef struct _IMAGE_THUNK_DATA {
union {
PDWORD Function;
PIMAGE_IMPORT_BY_NAME AddressOfData;
} u1;
} IMAGE_THUNK_DATA, *PIMAGE_THUNK_DATA;
Members
OriginalFirstThunk It points to the first thunk,
IMAGE_THUNK_DATA
, the thunk holds the address of the Hint and the Function name.TimeDateStamp It cotains the time/data stamp if there is the binding. If it is 0, no bound in imported DLL has happened. In new days, it sets to 0xFFFFFFFF to describe the binding occurred.
ForwarderChain In old version of binding, it referees to first forwarder chain of API. It can be set 0xFFFFFFFF to describe no forwarder.
Name It shows the relative virtual address of DLL name.
FirstThunk It contains the virtual address of the first thunk arrays that is defined by
IMAGE_THUNK_DATA
, the thunk is initialized by loader with function virtual address. In the absence view of the Orignal First Thunk, it points to the first thunk, the thunks of the Hints and The Function names.
PCHAR pHintName;
DWORD dwAPIaddress;
PCHAR pDllName;
PCHAR pAPIName;
// ----------------------------------------
DWORD dwImportDirectory = RVA2Offset(pImageBase, pimage_nt_headers -> OptionalHeader.
DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
// ----------------------------------------
PIMAGE_IMPORT_DESCRIPTOR pimage_import_descriptor = (PIMAGE_IMPORT_DESCRIPTOR)
(pImageBase + dwImportDirectory);
// ----------------------------------------
while (pimage_import_descriptor -> Name != 0 )
... {
pThunk= pImageBase+pimage_import_descriptor->FirstThunk;
pHintName= pImageBase;
if(pimage_import_descriptor->OriginalFirstThunk!=0)
...{
pHintName+= RVA2Offset(pImageBase, pimage_import_descriptor->OriginalFirstThunk);
}
else
...{
pHintName+= RVA2Offset(pImageBase, pimage_import_descriptor->FirstThunk);
}
pDllName= pImageBase + RVA2Offset(pImageBase, pimage_import_descriptor->Name);
printf(" DLL Name: %s First Thunk: 0x%x", pDllName,
pimage_import_descriptor->FirstThunk);
PIMAGE_THUNK_DATA pimage_thunk_data= (PIMAGE_THUNK_DATA) pHintName;
while(pimage_thunk_data->u1.AddressOfData!=0)
...{
dwAPIaddress= pimage_thunk_data->u1.AddressOfData;
if((dwAPIaddress&0x80000000)==0x80000000)
...{
dwAPIaddress&= 0x7FFFFFFF;
printf("Proccess: 0x%x", dwAPIaddress);
}
else
...{
pAPIName= pImageBase+RVA2Offset(pImageBase, dwAPIaddress)+2;
printf("Proccess: %s", pAPIName);
}
pThunk+= 4;
pHintName+= 4;
pimage_thunk_data++;
}
pimage_import_descriptor++;
}