Code:
#include <stdio.h>
#include <windows.h>
#include <ctype.h>
#include "gpa.h"
typedef FARPROC (*GPA)(HMODULE, LPCSTR);
PEB *getPEBaddr(void)
{
asm(
"MOVL %fs:(0x30), %eax;"
"LEAVE;"
"RET;"
);
}
int unicode_ascii_equal(char *as, UNICODE_STRING *us)
{
int i;
if (strlen(as) != ((int) us->Length / 2))
{
return 1;
}
for(i = 0; as[i]; i++)
{
if (tolower(as[i]) != tolower(((char *) us->Buffer)[2 * i]))
{
return i + 2;
}
}
return 0;
}
int main(void)
{
int i;
int offset;
int ordinal;
int SymbolRVA;
short *ExportOrdinalTable;
int *ExportAddressTable;
int index;
PEB *peb;
PEB_LDR_DATA *pld;
LDR_MODULE *ldrm;
IMAGE_DOS_HEADER *idh;
IMAGE_NT_HEADERS *inh;
IMAGE_EXPORT_DIRECTORY *ied;
GPA _GetProcAddress;
peb = getPEBaddr();
pld = peb->Ldr;
ldrm = (LDR_MODULE *) pld->InLoadOrderModuleList.Flink;
while(ldrm->BaseAddress && unicode_ascii_equal("kernel32.dll", &ldrm->BaseDllName) != 0)
{
ldrm = (LDR_MODULE *) ldrm->InLoadOrderModuleList.Flink;
}
if (!ldrm->BaseAddress)
{
return 1;
}
printf("kernel32.dll addr = 0x%08X\n", ldrm->BaseAddress);
idh = (IMAGE_DOS_HEADER *) ldrm->BaseAddress;
inh = (IMAGE_NT_HEADERS *) (ldrm->BaseAddress + idh->e_lfanew);
if (inh->OptionalHeader.DataDirectory[0].Size > 0)
{
ied = (IMAGE_EXPORT_DIRECTORY *) (ldrm->BaseAddress + inh->OptionalHeader.DataDirectory[0].VirtualAddress);
printf("%d functions\n", ied->NumberOfFunctions);
offset = ied->AddressOfNames;
for(i = 0; i < ied->NumberOfFunctions; i++)
{
index = *((int *) (ldrm->BaseAddress + offset));
//printf("%s\n", ldrm->BaseAddress + index);
if (!strcmp((char *) (ldrm->BaseAddress + index), "GetProcAddress"))
{
printf("---------> function found! (i = %d [0x%X])\n", i, i);
ExportOrdinalTable = (short *) (ldrm->BaseAddress + ied->AddressOfNameOrdinals);
ordinal = ExportOrdinalTable[i];
printf("ordinal = %d\n", ordinal);
ExportAddressTable = (int *) (ldrm->BaseAddress + ied->AddressOfFunctions);
SymbolRVA = ExportAddressTable[ordinal];
printf("GPA = %X [RVA]\n", SymbolRVA);
printf("GPA = %X\n", ldrm->BaseAddress + SymbolRVA);
_GetProcAddress = (GPA) (ldrm->BaseAddress + SymbolRVA);
break;
}
offset += 4;
}
}
// _GetProcAddress := address of GetProcAddress in kernel32.dll
return 0;
}