Author Topic: Calculating entrypoint and mapping it to byte array  (Read 2616 times)

0 Members and 1 Guest are viewing this topic.

Offline seci

  • Serf
  • *
  • Posts: 22
  • Cookies: 8
  • Seci :D
    • View Profile
    • www.evilzone.org
Calculating entrypoint and mapping it to byte array
« on: May 22, 2011, 04:08:47 am »
Hello

I am just fooling around trying to make something that may look like a disassembler in the end, nothing fancy. Just trying to gain some knowledge :) What I want to do is reading a whole executable into a byte array, calculating the entry point(the very first line of machine code that will get executed) and map it to a index in the byte array to read it. Now, I have been at this for a while now. Sitting in IDA and compiler/debugger trying to see if I can find numbers that match up to the values I have found other ways than calculating them programmatically, but with little luck.

Anyone mind lending me their brains?
« Last Edit: May 22, 2011, 04:09:00 am by seci »
6b619af0d7042db45f3e215b3dd7b977e8d1c82f

Offline ca0s

  • VIP
  • Sir
  • *
  • Posts: 432
  • Cookies: 53
    • View Profile
    • ka0labs #
Re: Calculating entrypoint and mapping it to byte array
« Reply #1 on: May 22, 2011, 02:17:54 pm »
You have to look at the PE structure. First you have the DOS header, which ha a pointer to the PE header. This one has a pointer to the optional header, where you have the entrypoint address. In C you have those structs to work with, when I have access to my lap I will post an example, if you still need it.

Offline seci

  • Serf
  • *
  • Posts: 22
  • Cookies: 8
  • Seci :D
    • View Profile
    • www.evilzone.org
Re: Calculating entrypoint and mapping it to byte array
« Reply #2 on: May 22, 2011, 03:45:32 pm »
You have to look at the PE structure. First you have the DOS header, which ha a pointer to the PE header. This one has a pointer to the optional header, where you have the entrypoint address. In C you have those structs to work with, when I have access to my lap I will post an example, if you still need it.

I was up rather late yesterday and read a lot about the PE/COFF structure and its headers, started building some structs and reading in a bit of data to them. I seam to get the hang of it now, but please. Do post examples if you can :)
6b619af0d7042db45f3e215b3dd7b977e8d1c82f

Offline ca0s

  • VIP
  • Sir
  • *
  • Posts: 432
  • Cookies: 53
    • View Profile
    • ka0labs #
Re: Calculating entrypoint and mapping it to byte array
« Reply #3 on: May 22, 2011, 03:57:44 pm »
Ok, here is something I started time ago and forgotten:

Code: [Select]
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <sys/stat.h>

FILE *f=NULL;
struct stat myStat;
int fileSize=0;


int main(int argc, char *argv[])
{
    printf("PE Analysis\n");
    if(argc<2) error("Usage: analysis programa.exe\n");
    f=fopen(argv[1], "rb");
    if(f==NULL) error("File not found.\n");
    stat(argv[1], &myStat);
    fileSize=myStat.st_size;
    char *fileMap = (char *)malloc(fileSize);
    fread(fileMap, fileSize, 1, f);
    fclose(f);
    printf("Tamaño: %i\n", fileSize);
    PIMAGE_DOS_HEADER IDH = (PIMAGE_DOS_HEADER)fileMap;
    PIMAGE_NT_HEADERS INT = (PIMAGE_NT_HEADERS)(fileMap + IDH->e_lfanew);
   
    printf("Type of machine -> %.4X\nNumber of sections -> %.2X\nEP -> %.4X", INT->FileHeader.Machine, INT->FileHeader.NumberOfSections, INT->OptionalHeader.AddressOfEntryPoint);
   
  return 0;
}

void error(char *error)
{
    printf("%s", error);
    exit(0);
}

Hope it helps you.

Offline seci

  • Serf
  • *
  • Posts: 22
  • Cookies: 8
  • Seci :D
    • View Profile
    • www.evilzone.org
Re: Calculating entrypoint and mapping it to byte array
« Reply #4 on: May 22, 2011, 05:35:45 pm »
Okay so. I have managed to read in the IMAGE_DOS_HEADER structure, locate the PE header address, address of the IMAGE_NT_HEADERS structure. Read in the IMAGE_NT_HEADERS signature. Read the IMAGE_FILE_HEADER inside the IMAGE_NT_HEADERS structure. Read big parts of IMAGE_OPTIONAL_HEADER which is also a part of IMAGE_NT_HEADERS. However, the last bit in IMAGE_OPTIONAL_HEADER got me confused;

The DataDirectory structure inside IMAGE_OPTIONAL_HEADER, IMAGE_DATA_DIRECTORY. Its an array of the structure IMAGE_DATA_DIRECTORY, which is 2x 4 bytes(VirtualAddress and isize DWORD's). The array length is 16, so 16 * 8 bytes = 128 bytes. However, I don't understand where to read this/these structures.

The last DWORD successfully read in IMAGE_OPTIONAL_HEADER is NumberOfRvaAndSizes and right after that is the array of the structure IMAGE_DATA_DIRECTORY, DataDirectory[]. Now, where do you read those IMAGE_DATA_DIRECTORY[]'s? It dosen't fit right after the NumberOfRvaAndSizes.. Rather, it doesn't match up.



EDIT:

Okay, wait! I just read trough my old comments:
Code: [Select]
        // DWORD NumberOfRvaAndSizes                     // [b]The length of the DataDirectory array that follows[/b].                     // 4 bytes
        // IMAGE_DATA_DIRECTORY DataDirectory[]     // An array of IMAGE_DATA_DIRECTORY, lenght = 16                      // 8 bytes * 16

So, am I right if I am supposed to read the next 8 bytes * (NumberOfRvaAndSizes/8) into structures of IMAGE_DATA_DIRECTORY?
« Last Edit: May 22, 2011, 05:38:34 pm by seci »
6b619af0d7042db45f3e215b3dd7b977e8d1c82f

Offline ca0s

  • VIP
  • Sir
  • *
  • Posts: 432
  • Cookies: 53
    • View Profile
    • ka0labs #
Re: Calculating entrypoint and mapping it to byte array
« Reply #5 on: May 22, 2011, 06:08:09 pm »
I have not enought knoweldge to aswer you trusting myself, sorry. I think we know more or less the same about this topic. I attach you a rar with various PDFs about PE. There is one og them, called "PE format", which is a diagram of the PE structure and the structs it is composed of.

Offline seci

  • Serf
  • *
  • Posts: 22
  • Cookies: 8
  • Seci :D
    • View Profile
    • www.evilzone.org
Re: Calculating entrypoint and mapping it to byte array
« Reply #6 on: May 22, 2011, 06:19:54 pm »
I have not enought knoweldge to aswer you trusting myself, sorry. I think we know more or less the same about this topic. I attach you a rar with various PDFs about PE. There is one og them, called "PE format", which is a diagram of the PE structure and the structs it is composed of.

Ah yes, that diagram actually helped a bit. Thanks ca0s, you have been great help :) Further comments are welcome.
6b619af0d7042db45f3e215b3dd7b977e8d1c82f

Offline ca0s

  • VIP
  • Sir
  • *
  • Posts: 432
  • Cookies: 53
    • View Profile
    • ka0labs #
Re: Calculating entrypoint and mapping it to byte array
« Reply #7 on: May 22, 2011, 10:09:45 pm »
We could keep this thread alive with our research in this topic. It could be helpful to both us and the rest of people interested.

Offline seci

  • Serf
  • *
  • Posts: 22
  • Cookies: 8
  • Seci :D
    • View Profile
    • www.evilzone.org
Re: Calculating entrypoint and mapping it to byte array
« Reply #8 on: May 22, 2011, 10:49:50 pm »
We could keep this thread alive with our research in this topic. It could be helpful to both us and the rest of people interested.

Sure, ill post up some info when I have done a bit more coding and things are starting to work :)
6b619af0d7042db45f3e215b3dd7b977e8d1c82f

Offline ca0s

  • VIP
  • Sir
  • *
  • Posts: 432
  • Cookies: 53
    • View Profile
    • ka0labs #
Re: Calculating entrypoint and mapping it to byte array
« Reply #9 on: May 24, 2011, 02:26:11 pm »
I got to print which DLL's an EXE loads, and which APIS from each DLL.

Code: [Select]
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <sys/stat.h>

FILE *f=NULL;
struct stat myStat;
int fileSize=0;


int main(int argc, char *argv[])
{
    printf("PE Analysis\n");
    if(argc<2) error("Uso: analysis programa.exe\n");
    f=fopen(argv[1], "rb");
    if(f==NULL) error("Archivo no encontrado.\n");
    stat(argv[1], &myStat);
    fileSize=myStat.st_size;
    char *fileMap = (char *)malloc(fileSize);
    fread(fileMap, fileSize, 1, f);
    fclose(f);
    printf("Tamaño: %i\n", fileSize);
    PIMAGE_DOS_HEADER IDH = (PIMAGE_DOS_HEADER)fileMap;
    PIMAGE_NT_HEADERS INT = (PIMAGE_NT_HEADERS)(fileMap + IDH->e_lfanew);
   
    printf("Type of machine -> %.4X\nNumber of sections -> %.2X\nEP -> %.4X\n\n", INT->FileHeader.Machine, INT->FileHeader.NumberOfSections, INT->OptionalHeader.AddressOfEntryPoint);
   
    IMAGE_DATA_DIRECTORY imports = (IMAGE_DATA_DIRECTORY)(INT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]); // IMAGE_DIRECTORY_ENTRY_IMPORT
   
    int i=0;
    PIMAGE_SECTION_HEADER SH, iSH;
    for(i=0; i<INT->FileHeader.NumberOfSections; i++)
    {
        SH=(PIMAGE_SECTION_HEADER)(fileMap + IDH->e_lfanew + sizeof(IMAGE_NT_HEADERS) + sizeof(IMAGE_SECTION_HEADER)*i);
        if(imports.VirtualAddress >= SH->VirtualAddress) iSH=SH;
        printf("%s \t- %.4X\n", SH->Name, SH->VirtualAddress);
    }
   
    //printf("%.4X - %.4X\n", iSH->VirtualAddress, iSH->PointerToRawData);
    printf("\nRVA IAT: %.4X\nFisica: %.4X\nSize: %.4X\n\n", imports.VirtualAddress, imports.VirtualAddress - iSH->VirtualAddress + iSH->PointerToRawData, imports.Size);
   
    PIMAGE_IMPORT_DESCRIPTOR IID = (PIMAGE_IMPORT_DESCRIPTOR)(fileMap + (imports.VirtualAddress - iSH->VirtualAddress + iSH->PointerToRawData));
    PIMAGE_THUNK_DATA TD;
    PIMAGE_IMPORT_BY_NAME IBN;
    for(; IID->Name; IID++)
    {
        printf("%s\n", fileMap + IID->Name - iSH->VirtualAddress + iSH->PointerToRawData);
        TD = (PIMAGE_THUNK_DATA)((DWORD)fileMap + IID->FirstThunk - iSH->VirtualAddress + iSH->PointerToRawData);
        for(; TD->u1.Ordinal; TD++)
        {
            //printf("%.4X\n", fileMap + TD->u1.Function - iSH->VirtualAddress + iSH->PointerToRawData);
            IBN = (PIMAGE_IMPORT_BY_NAME)(fileMap + TD->u1.Function - iSH->VirtualAddress + iSH->PointerToRawData);
            //printf("%.4X\n", IBN->Hint);
            printf("\t%s\n", IBN->Name);
        }
    }
   
  return 0;
}

void error(char *error)
{
    printf("%s", error);
    exit(0);
}