#define NTOSAPI #include #include #include #include "rossympriv.h" #include #define NDEBUG #include #include "dwarf.h" #include "pe.h" #include "rossympriv.h" PeSect *pesection(Pe *pe, const char *name) { int i; ANSI_STRING WantName; RtlInitAnsiString(&WantName, name); DPRINT("Searching for section %s\n", name); for (i = 0; i < pe->nsections; i++) { PANSI_STRING AnsiString = ANSI_NAME_STRING(&pe->sect[i]); if (WantName.Length == AnsiString->Length && !memcmp(AnsiString->Buffer, name, WantName.Length)) { DPRINT("Found %s (%d) @ %x (%x)\n", name, i, ((PCHAR)pe->imagebase)+pe->sect[i].VirtualAddress, pe->sect[i].SizeOfRawData); return &pe->sect[i]; } } DPRINT("%s not found\n", name); return nil; } u16int peget2(const unsigned char *ptr) { return *((u16int*)ptr); } u32int peget4(const unsigned char *ptr) { return *((u32int*)ptr); } u64int peget8(const unsigned char *ptr) { return *((u64int*)ptr); } int readn(void *filectx, char *buffer, ulong size) { return RosSymReadFile(filectx, buffer, size); } int seek(void *filectx, ulong position, int origin) { assert(origin == 0); return RosSymSeekFile(filectx, position); } static int readblock(void *fd, DwarfBlock *b, ulong off, ulong len) { b->data = malloc(len); if(b->data == nil) return -1; if(!seek(fd, off, 0) || !readn(fd, (char *)b->data, len)){ free(b->data); b->data = nil; return -1; } b->len = len; return 0; } int loaddisksection(Pe *pe, char *name, DwarfBlock *b) { PeSect *s; if((s = pesection(pe, name)) == nil) return -1; return readblock(pe->fd, b, s->PointerToRawData, s->SizeOfRawData); } int loadmemsection(Pe *pe, char *name, DwarfBlock *b) { PeSect *s; if((s = pesection(pe, name)) == nil) return -1; DPRINT("Loading section %s (ImageBase %x RVA %x)\n", name, pe->fd, s->VirtualAddress); b->data = RosSymAllocMem(s->SizeOfRawData); b->len = s->SizeOfRawData; PCHAR DataSource = ((char *)pe->fd) + s->VirtualAddress; DPRINT("Copying to %x from %x (%x)\n", DataSource, b->data, b->len); RtlCopyMemory(b->data, DataSource, s->SizeOfRawData); return s->SizeOfRawData; } void *RosSymAllocMemZero(ulong size, ulong count) { void *res = RosSymAllocMem(size * count); if (res) memset(res, 0, size * count); return res; } int GetStrnlen(const char *string, int maxlen) { int i; for (i = 0; i < maxlen && string[i]; i++); return i; } void pefree(Pe *pe) { int i; for (i = 0; i < pe->nsections; i++) { RtlFreeAnsiString(ANSI_NAME_STRING(&pe->sect[i])); } for (i = 0; i < pe->nsymbols; i++) { free(pe->symtab[i].name); } free(pe->symtab); free(pe->sect); free(pe); } void xfree(void *v) { if (v) RosSymFreeMem(v); } ulong pefindrva(struct _IMAGE_SECTION_HEADER *SectionHeaders, int NumberOfSections, ulong TargetPhysical) { int i; DPRINT("Finding RVA for Physical %x\n", TargetPhysical); for (i = 0; i < NumberOfSections; i++) { DPRINT("Section %d name %s Raw %x Virt %x\n", i, ANSI_NAME_STRING(&SectionHeaders[i])->Buffer, SectionHeaders[i].PointerToRawData, SectionHeaders[i].VirtualAddress); if (TargetPhysical >= SectionHeaders[i].PointerToRawData && TargetPhysical < SectionHeaders[i].PointerToRawData + SectionHeaders[i].SizeOfRawData) { DPRINT("RVA %x\n", TargetPhysical - SectionHeaders[i].PointerToRawData + SectionHeaders[i].VirtualAddress); return TargetPhysical - SectionHeaders[i].PointerToRawData + SectionHeaders[i].VirtualAddress; } } return nil; }