mirror of
https://github.com/reactos/reactos.git
synced 2025-04-25 08:00:24 +00:00
[RSYM64] Nuke rsym64
It's purpose was to create x64 unwind information from DWARF debug info, but it was never fully working and is pointless now anyway, because x64 GCC does this itself properly.
This commit is contained in:
parent
5d30831fb8
commit
4a5fdb9a3a
7 changed files with 17 additions and 1137 deletions
|
@ -157,7 +157,10 @@ if(NOT CMAKE_CROSSCOMPILING)
|
|||
|
||||
set(NATIVE_TARGETS asmpp bin2c widl gendib cabman fatten hpp isohybrid mkhive mkisofs obj2bin spec2def geninc mkshelllink utf16le xml2sdb)
|
||||
if(NOT MSVC)
|
||||
list(APPEND NATIVE_TARGETS rsym pefixup)
|
||||
list(APPEND NATIVE_TARGETS pefixup)
|
||||
if (ARCH STREQUAL "i386")
|
||||
list(APPEND NATIVE_TARGETS rsym)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
install(TARGETS ${NATIVE_TARGETS})
|
||||
|
|
|
@ -14,6 +14,8 @@ endif()
|
|||
# Dwarf based builds (no rsym)
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
set(NO_ROSSYM TRUE)
|
||||
elseif(NOT ARCH STREQUAL "i386")
|
||||
set(NO_ROSSYM TRUE)
|
||||
elseif(NOT DEFINED NO_ROSSYM)
|
||||
set(NO_ROSSYM FALSE)
|
||||
endif()
|
||||
|
|
|
@ -4,7 +4,10 @@ include(ExternalProject)
|
|||
function(setup_host_tools)
|
||||
list(APPEND HOST_TOOLS asmpp bin2c widl gendib cabman fatten hpp isohybrid mkhive mkisofs obj2bin spec2def geninc mkshelllink txt2nls utf16le xml2sdb)
|
||||
if(NOT MSVC)
|
||||
list(APPEND HOST_TOOLS rsym pefixup)
|
||||
list(APPEND HOST_TOOLS pefixup)
|
||||
if (ARCH STREQUAL "i386")
|
||||
list(APPEND HOST_TOOLS rsym)
|
||||
endif()
|
||||
endif()
|
||||
if ((ARCH STREQUAL "amd64") AND (CMAKE_C_COMPILER_ID STREQUAL "GNU"))
|
||||
execute_process(
|
||||
|
|
|
@ -34,10 +34,14 @@ add_subdirectory(hhpcomp)
|
|||
add_subdirectory(hpp)
|
||||
add_subdirectory(isohybrid)
|
||||
add_subdirectory(kbdtool)
|
||||
add_subdirectory(log2lines)
|
||||
if(ARCH STREQUAL "i386")
|
||||
add_subdirectory(log2lines)
|
||||
endif()
|
||||
add_subdirectory(mkhive)
|
||||
add_subdirectory(mkisofs)
|
||||
add_subdirectory(rsym)
|
||||
if(ARCH STREQUAL "i386")
|
||||
add_subdirectory(rsym)
|
||||
endif()
|
||||
add_subdirectory(txt2nls)
|
||||
add_subdirectory(unicode)
|
||||
add_subdirectory(widl)
|
||||
|
|
|
@ -3,15 +3,7 @@ include_directories(${REACTOS_SOURCE_DIR}/sdk/tools)
|
|||
add_library(rsym_common STATIC rsym_common.c)
|
||||
target_link_libraries(rsym_common PRIVATE host_includes)
|
||||
|
||||
if(ARCH STREQUAL "i386")
|
||||
add_host_tool(rsym rsym.c)
|
||||
elseif(ARCH STREQUAL "amd64")
|
||||
add_host_tool(rsym rsym64.c)
|
||||
elseif(ARCH STREQUAL "arm")
|
||||
add_executable(rsym rsym64.c)
|
||||
elseif(ARCH STREQUAL "arm64")
|
||||
add_executable(rsym rsym64.c)
|
||||
endif()
|
||||
add_host_tool(rsym rsym.c)
|
||||
|
||||
target_link_libraries(rsym PRIVATE host_includes rsym_common dbghelphost unicode)
|
||||
add_host_tool(raddr2line raddr2line.c)
|
||||
|
|
|
@ -1,936 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "rsym.h"
|
||||
#include "rsym64.h"
|
||||
#include "dwarf2.h"
|
||||
|
||||
char DoPrint = 0;
|
||||
ULONG g_ehframep;
|
||||
|
||||
#define DPRINT if(DoPrint) printf
|
||||
|
||||
struct {char *name; char regnt;} regs[] =
|
||||
{ {"rax", REG_RAX}, {"rdx", REG_RDX}, {"rcx", REG_RCX}, {"rbx", REG_RBX},
|
||||
{"rsi", REG_RSI}, {"rdi", REG_RDI}, {"rbp", REG_RBP}, {"rsp", REG_RSP},
|
||||
{"r8", REG_R8}, {"r9", REG_R9}, {"r10", REG_R10}, {"r11", REG_R11},
|
||||
{"r12", REG_R12}, {"r13", REG_R13}, {"r14", REG_R14}, {"r15", REG_R15},
|
||||
{"xmm0", REG_XMM0}, {"xmm1", REG_XMM1}, {"xmm2", REG_XMM2}, {"xmm3", REG_XMM3},
|
||||
{"xmm4", REG_XMM4}, {"xmm5", REG_XMM5}, {"xmm6", REG_XMM6}, {"xmm7", REG_XMM7},
|
||||
{"xmm8", REG_XMM8}, {"xmm9", REG_XMM9}, {"xmm10",REG_XMM10},{"xmm11",REG_XMM11},
|
||||
{"xmm12",REG_XMM12},{"xmm13",REG_XMM13},{"xmm14",REG_XMM14},{"xmm15",REG_XMM15},
|
||||
// "st0", "st1", "st2", "st3",
|
||||
// "st4", "st5", "st6", "st7",
|
||||
// "mm0", "mm1", "mm2", "mm3",
|
||||
// "mm4", "mm5", "mm6", "mm7"
|
||||
};
|
||||
|
||||
/** Functions for DWARF2 ******************************************************/
|
||||
|
||||
unsigned long
|
||||
DwDecodeUleb128(unsigned long *pResult, char *pc)
|
||||
{
|
||||
unsigned long ulResult = 0;
|
||||
unsigned long ulShift = 0;
|
||||
unsigned char current;
|
||||
unsigned long ulSize = 0;
|
||||
|
||||
do
|
||||
{
|
||||
current = pc[ulSize];
|
||||
ulSize++;
|
||||
ulResult |= (current & 0x7f) << ulShift;
|
||||
ulShift += 7;
|
||||
}
|
||||
while (current & 0x80);
|
||||
|
||||
*pResult = ulResult;
|
||||
return ulSize;
|
||||
}
|
||||
|
||||
unsigned long
|
||||
DwDecodeSleb128(long *pResult, char *pc)
|
||||
{
|
||||
long lResult = 0;
|
||||
unsigned long ulShift = 0;
|
||||
unsigned char current;
|
||||
unsigned long ulSize = 0;
|
||||
|
||||
do
|
||||
{
|
||||
current = pc[ulSize];
|
||||
ulSize++;
|
||||
lResult |= (current & 0x7f) << ulShift;
|
||||
ulShift += 7;
|
||||
}
|
||||
while (current & 0x80);
|
||||
|
||||
if (current & 0x40)
|
||||
lResult |= - (1 << (ulShift));
|
||||
|
||||
*pResult = lResult;
|
||||
|
||||
return ulSize;
|
||||
}
|
||||
|
||||
unsigned long
|
||||
DwDecodeCie(PDW2CIE Cie, char *pc)
|
||||
{
|
||||
Cie->Length = *(ULONG*)pc;
|
||||
Cie->Next = pc + 4 + Cie->Length;
|
||||
Cie->CieId = *(ULONG*)(pc + 4);
|
||||
Cie->Version = pc[8];
|
||||
Cie->AugString = pc + 9;
|
||||
Cie->AugStringLength = strlen(Cie->AugString);
|
||||
pc = Cie->AugString + Cie->AugStringLength + 1;
|
||||
pc += DwDecodeUleb128(&Cie->CodeAlign, pc);
|
||||
pc += DwDecodeSleb128(&Cie->DataAlign, pc);
|
||||
pc += DwDecodeUleb128(&Cie->ReturnAddressRegister, pc);
|
||||
pc += DwDecodeUleb128(&Cie->AugLength, pc);
|
||||
Cie->AugData = pc;
|
||||
pc += Cie->AugLength;
|
||||
Cie->Instructions = pc;
|
||||
|
||||
return Cie->Length + 4;
|
||||
}
|
||||
|
||||
unsigned long
|
||||
DwDecodeFde(PDW2FDE Fde, char *pc)
|
||||
{
|
||||
Fde->Length = *(ULONG*)pc;
|
||||
Fde->Next = pc + 4 + Fde->Length;
|
||||
Fde->CiePointer = pc + 4 - *(ULONG*)(pc + 4);
|
||||
Fde->PcBegin = *(ULONG*)(pc + 8);
|
||||
Fde->PcRange = *(ULONG*)(pc + 12);
|
||||
pc += 16;
|
||||
pc += DwDecodeUleb128(&Fde->AugLength, pc);
|
||||
Fde->AugData = pc;
|
||||
Fde->Instructions = Fde->AugData + Fde->AugLength;
|
||||
|
||||
return Fde->Length + 4;
|
||||
}
|
||||
|
||||
unsigned long
|
||||
DwExecIntruction(PDW2CFSTATE State, char *pc)
|
||||
{
|
||||
unsigned char Code;
|
||||
unsigned long Length;
|
||||
unsigned long PrevFramePtr = State->FramePtr;
|
||||
|
||||
State->Scope = 0;
|
||||
State->IsUwop = 0;
|
||||
State->Code = Code = *pc;
|
||||
Length = 1;
|
||||
if ((Code & 0xc0) == DW_CFA_advance_loc)
|
||||
{
|
||||
State->Code = DW_CFA_advance_loc;
|
||||
State->Location += Code & 0x3f;
|
||||
}
|
||||
else if ((Code & 0xc0) == DW_CFA_offset)
|
||||
{
|
||||
State->Code = DW_CFA_offset;
|
||||
State->Reg = Code & 0x3f;
|
||||
Length += DwDecodeUleb128((unsigned long*)&State->Offset, pc + 1);
|
||||
State->Offset *= 8; // fixme data alignment
|
||||
State->IsUwop = 1;
|
||||
}
|
||||
else if ((Code & 0xc0) == DW_CFA_restore)
|
||||
{
|
||||
State->Code = DW_CFA_restore;
|
||||
State->Reg = Code & 0x3f;
|
||||
}
|
||||
else switch (Code)
|
||||
{
|
||||
case DW_CFA_nop:
|
||||
break;
|
||||
case DW_CFA_set_loc:
|
||||
Length = 9; // address
|
||||
State->Location = *(DWORD*)(pc + 1);
|
||||
break;
|
||||
case DW_CFA_advance_loc1:
|
||||
Length = 2;
|
||||
State->Location += pc[1];
|
||||
break;
|
||||
case DW_CFA_advance_loc2:
|
||||
Length = 3;
|
||||
// printf("Found a DW_CFA_advance_loc2 : 0x%lx ->", *(WORD*)(pc + 1));
|
||||
State->Location += *(WORD*)(pc + 1);
|
||||
// printf(" 0x%lx\n", State->Location);
|
||||
break;
|
||||
case DW_CFA_advance_loc4:
|
||||
Length = 5;
|
||||
// printf("Found a DW_CFA_advance_loc4 : 0x%lx ->", *(DWORD*)(pc + 1));
|
||||
State->Location += *(DWORD*)(pc + 1);
|
||||
// printf(" 0x%lx\n", State->Location);
|
||||
break;
|
||||
case DW_CFA_offset_extended:
|
||||
Length += DwDecodeUleb128(&State->Reg, pc + Length);
|
||||
Length += DwDecodeUleb128((unsigned long*)&State->Offset, pc + Length);
|
||||
State->IsUwop = 1;
|
||||
break;
|
||||
case DW_CFA_offset_extended_sf:
|
||||
Length += DwDecodeUleb128(&State->Reg, pc + Length);
|
||||
Length += DwDecodeSleb128(&State->Offset, pc + Length);
|
||||
State->IsUwop = 1;
|
||||
break;
|
||||
case DW_CFA_restore_extended:
|
||||
Length += DwDecodeUleb128(&State->Reg, pc + Length);
|
||||
break;
|
||||
case DW_CFA_undefined:
|
||||
Length += DwDecodeUleb128(&State->Reg, pc + Length);
|
||||
break;
|
||||
case DW_CFA_same_value:
|
||||
Length += DwDecodeUleb128(&State->Reg, pc + Length);
|
||||
break;
|
||||
case DW_CFA_register:
|
||||
Length += DwDecodeUleb128(&State->Reg, pc + Length);
|
||||
Length += DwDecodeUleb128(&State->Reg2, pc + Length);
|
||||
break;
|
||||
case DW_CFA_remember_state:
|
||||
break;
|
||||
case DW_CFA_restore_state:
|
||||
break;
|
||||
case DW_CFA_def_cfa:
|
||||
Length += DwDecodeUleb128(&State->Reg, pc + Length);
|
||||
Length += DwDecodeUleb128((unsigned long*)&State->FramePtr, pc + Length);
|
||||
State->IsUwop = 1;
|
||||
break;
|
||||
case DW_CFA_def_cfa_register:
|
||||
Length += DwDecodeUleb128(&State->Reg, pc + Length);
|
||||
break;
|
||||
case DW_CFA_def_cfa_offset:
|
||||
Length += DwDecodeUleb128((unsigned long*)&State->FramePtr, pc + Length);
|
||||
State->IsUwop = 1;
|
||||
break;
|
||||
case DW_CFA_def_cfa_sf:
|
||||
Length += DwDecodeUleb128(&State->Reg, pc + Length);
|
||||
Length += DwDecodeSleb128(&State->FramePtr, pc + Length);
|
||||
State->FramePtr *= 8; // data alignment
|
||||
State->IsUwop = 1;
|
||||
break;
|
||||
case DW_CFA_GNU_args_size:
|
||||
{
|
||||
unsigned long argsize;
|
||||
printf("Warning, DW_CFA_GNU_args_size is unimplemented\n");
|
||||
Length += DwDecodeUleb128(&argsize, pc + Length);
|
||||
break;
|
||||
}
|
||||
/* PSEH */
|
||||
case 0x21:
|
||||
{
|
||||
unsigned long SehType;
|
||||
|
||||
// printf("found 0x21 at %lx\n", State->Location);
|
||||
Length += DwDecodeUleb128(&SehType, pc + Length);
|
||||
switch (SehType)
|
||||
{
|
||||
case 1: /* Begin Try */
|
||||
State->TryLevel++;
|
||||
if (State->TryLevel >= 20)
|
||||
{
|
||||
printf("WTF? Trylevel of 20 exceeded...\n");
|
||||
exit(1);
|
||||
}
|
||||
State->SehBlock[State->TryLevel-1].BeginTry = State->Location;
|
||||
// printf("Found begintry at 0x%lx\n", State->Location);
|
||||
State->Scope = 1;
|
||||
break;
|
||||
|
||||
case 2: /* End Try */
|
||||
State->SehBlock[State->TryLevel-1].EndTry = State->Location;
|
||||
State->Scope = 2;
|
||||
break;
|
||||
|
||||
case 3: /* Jump target */
|
||||
State->SehBlock[State->TryLevel-1].Target = State->Location;
|
||||
State->Scope = 3;
|
||||
break;
|
||||
|
||||
case 4: /* SEH End */
|
||||
if (State->TryLevel == 20)
|
||||
{
|
||||
printf("Ooops, end of SEH with trylevel at 0!\n");
|
||||
exit(1);
|
||||
}
|
||||
State->SehBlock[State->TryLevel-1].End = State->Location;
|
||||
State->TryLevel--;
|
||||
State->cScopes++;
|
||||
State->Scope = 0;
|
||||
break;
|
||||
|
||||
case 5: /* Constant filter */
|
||||
{
|
||||
unsigned long value;
|
||||
Length += DwDecodeUleb128(&value, pc + Length);
|
||||
State->SehBlock[State->TryLevel-1].Handler = value;
|
||||
// printf("Found a constant filter at 0x%lx\n", State->Location);
|
||||
break;
|
||||
}
|
||||
|
||||
/* These work differently. We are in a new function.
|
||||
* We have to parse a lea opcode to find the address of
|
||||
* the jump target. This is the reference to find the
|
||||
* appropriate C_SCOPE_TABLE. */
|
||||
case 6: /* Filter func */
|
||||
// printf("Found a filter func at 0x%lx\n", State->Location);
|
||||
break;
|
||||
|
||||
case 7: /* Finally func */
|
||||
{
|
||||
// printf("Found a finally func at 0x%lx\n", State->Location);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
printf("Found unknow PSEH code 0x%lx\n", SehType);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
fprintf(stderr, "unknown instruction 0x%x at 0x%p\n", Code, pc);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
State->FramePtrDiff = State->FramePtr - PrevFramePtr;
|
||||
DPRINT("@%p: code=%x, Loc=%lx, offset=%lx, reg=0x%lx:%s\n",
|
||||
(void*)((ULONG)pc - g_ehframep), Code, State->Location, State->Offset, State->Reg, regs[State->Reg].name);
|
||||
return Length;
|
||||
}
|
||||
|
||||
/** Windows unwind data functions *********************************************/
|
||||
|
||||
ULONG
|
||||
StoreUnwindCodes(PUNWIND_INFO Info, PDW2CFSTATE State, ULONG FunctionStart)
|
||||
{
|
||||
ULONG cCodes = 0;
|
||||
ULONG AllocSize;
|
||||
UNWIND_CODE Code[3];
|
||||
int i;
|
||||
|
||||
Code[0].CodeOffset = State->Location - FunctionStart;
|
||||
|
||||
switch (State->Code)
|
||||
{
|
||||
case DW_CFA_offset:
|
||||
case DW_CFA_offset_extended:
|
||||
// save register at offset
|
||||
Code[0].OpInfo = regs[State->Reg].regnt;
|
||||
if (State->Offset <= 0x7FFF8)
|
||||
{
|
||||
Code[0].UnwindOp = UWOP_SAVE_NONVOL;
|
||||
Code[1].FrameOffset = State->Offset / 8;
|
||||
cCodes = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
Code[0].UnwindOp = UWOP_SAVE_NONVOL_FAR;
|
||||
Code[1].FrameOffset = (State->Offset / 8);
|
||||
Code[2].FrameOffset = (State->Offset / 8) >> 16;
|
||||
cCodes = 3;
|
||||
}
|
||||
break;
|
||||
|
||||
case DW_CFA_def_cfa:
|
||||
//case DW_CFA_def_cfa_register:
|
||||
case DW_CFA_def_cfa_offset:
|
||||
case DW_CFA_def_cfa_sf:
|
||||
AllocSize = State->FramePtrDiff;
|
||||
if (AllocSize <= 128)
|
||||
{
|
||||
Code[0].UnwindOp = UWOP_ALLOC_SMALL;
|
||||
Code[0].OpInfo = (AllocSize / 8) - 1;
|
||||
cCodes = 1;
|
||||
}
|
||||
else if (AllocSize <= 0x7FFF8)
|
||||
{
|
||||
Code[0].UnwindOp = UWOP_ALLOC_LARGE;
|
||||
Code[0].OpInfo = 0;
|
||||
Code[1].FrameOffset = AllocSize / 8;
|
||||
cCodes = 2;
|
||||
}
|
||||
else // if (AllocSize > 0x7FFF8)
|
||||
{
|
||||
Code[0].UnwindOp = UWOP_ALLOC_LARGE;
|
||||
Code[0].OpInfo = 1;
|
||||
Code[1].FrameOffset = (USHORT)AllocSize;
|
||||
Code[2].FrameOffset = (USHORT)(AllocSize >> 16);
|
||||
cCodes = 3;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (Info)
|
||||
{
|
||||
/* Move old codes */
|
||||
for (i = Info->CountOfCodes - 1; i >= 0; i--)
|
||||
{
|
||||
Info->UnwindCode[i + cCodes] = Info->UnwindCode[i];
|
||||
}
|
||||
|
||||
/* Copy new codes */
|
||||
for (i = 0; i < cCodes; i++)
|
||||
{
|
||||
Info->UnwindCode[i] = Code[i];
|
||||
}
|
||||
|
||||
Info->CountOfCodes += cCodes;
|
||||
}
|
||||
|
||||
return cCodes;
|
||||
}
|
||||
|
||||
#define GetxdataSize(cFuncs, cUWOP, cScopes) \
|
||||
( cFuncs * (sizeof(UNWIND_INFO) + 2 + 4 + 4) \
|
||||
+ cUWOP * sizeof(UNWIND_CODE) \
|
||||
+ cScopes * sizeof(C_SCOPE_TABLE_ENTRY) )
|
||||
|
||||
ULONG
|
||||
StoreUnwindInfo(PUNWIND_INFO Info, PDW2FDE pFde, ULONG FunctionStart)
|
||||
{
|
||||
ULONG cbSize;
|
||||
DW2CFSTATE State;
|
||||
char *pInst;
|
||||
ULONG c;
|
||||
DW2CIE Cie;
|
||||
|
||||
cbSize = 4; // sizeof(UNWIND_INFO);
|
||||
Info->Version = 1;
|
||||
Info->Flags = 0;
|
||||
Info->SizeOfProlog = 0;
|
||||
Info->CountOfCodes = 0;
|
||||
Info->FrameRegister = 0;
|
||||
Info->FrameOffset = 0;
|
||||
|
||||
/* Decode the CIE */
|
||||
DwDecodeCie(&Cie, pFde->CiePointer);
|
||||
|
||||
/* Initialize state */
|
||||
State.Location = FunctionStart;
|
||||
State.FramePtr = 0;
|
||||
State.TryLevel = 0;
|
||||
State.cScopes = 0;
|
||||
|
||||
/* Parse the CIE's initial instructions */
|
||||
pInst = Cie.Instructions;
|
||||
while (pInst < Cie.Next)
|
||||
{
|
||||
pInst += DwExecIntruction(&State, pInst);
|
||||
}
|
||||
|
||||
/* Parse the FDE instructions */
|
||||
pInst = pFde->Instructions;
|
||||
while (pInst < pFde->Next)
|
||||
{
|
||||
pInst += DwExecIntruction(&State, pInst);
|
||||
|
||||
if (State.IsUwop)
|
||||
{
|
||||
c = StoreUnwindCodes(Info, &State, FunctionStart);
|
||||
cbSize += c * sizeof(UNWIND_CODE);
|
||||
Info->SizeOfProlog = State.Location - FunctionStart;
|
||||
}
|
||||
}
|
||||
cbSize = ROUND_UP(cbSize, 4);
|
||||
|
||||
/* Do we have scope table to write? */
|
||||
if (State.cScopes > 0)
|
||||
{
|
||||
unsigned long i;
|
||||
ULONG *pExceptionHandler;
|
||||
PC_SCOPE_TABLE pScopeTable;
|
||||
|
||||
/* Set flag for exception handler */
|
||||
Info->Flags |= UNW_FLAG_EHANDLER;
|
||||
|
||||
/* Store address of handler and number of scope tables */
|
||||
pExceptionHandler = (ULONG*)((char*)Info + cbSize);
|
||||
// HACK for testing purpose
|
||||
*pExceptionHandler = FunctionStart; // _C_specific_handler
|
||||
|
||||
pScopeTable = (PC_SCOPE_TABLE)(pExceptionHandler + 1);
|
||||
pScopeTable->NumEntries = State.cScopes;
|
||||
|
||||
/* Store the scope table entries */
|
||||
for (i = 0; i < State.cScopes; i++)
|
||||
{
|
||||
pScopeTable->Entry[i].Begin = State.SehBlock[i].BeginTry;
|
||||
pScopeTable->Entry[i].End = State.SehBlock[i].EndTry;
|
||||
pScopeTable->Entry[i].Handler = 1;//State.SehBlock[i].Handler;
|
||||
pScopeTable->Entry[i].Target = State.SehBlock[i].Target;
|
||||
}
|
||||
|
||||
/* Update size */
|
||||
cbSize += 8 + State.cScopes * sizeof(C_SCOPE_TABLE_ENTRY);
|
||||
}
|
||||
|
||||
return cbSize;
|
||||
}
|
||||
|
||||
void
|
||||
CountUnwindData(PFILE_INFO File)
|
||||
{
|
||||
DW2CIEFDE *p;
|
||||
DW2FDE Fde;
|
||||
char *pInst, *pmax;
|
||||
DW2CFSTATE State;
|
||||
|
||||
File->cFuncs = 0;
|
||||
File->cScopes = 0;
|
||||
File->cUWOP = 0;
|
||||
State.FramePtr = 0;
|
||||
State.TryLevel = 0;
|
||||
|
||||
p = File->eh_frame.p;
|
||||
pmax = (char*)p + File->eh_frame.psh->Misc.VirtualSize;
|
||||
for (; p->Length && (char*)p < pmax; p = NextCIE(p))
|
||||
{
|
||||
/* Is this an FDE? */
|
||||
if (p->CiePointer != 0)
|
||||
{
|
||||
File->cFuncs++;
|
||||
DwDecodeFde(&Fde, (char*)p);
|
||||
|
||||
pInst = Fde.Instructions;
|
||||
while (pInst < Fde.Next)
|
||||
{
|
||||
pInst += DwExecIntruction(&State, pInst);
|
||||
File->cUWOP += StoreUnwindCodes(NULL, &State, 0);
|
||||
File->cScopes += State.Scope ? 1 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int CompFunc(const void *p1, const void *p2)
|
||||
{
|
||||
PRUNTIME_FUNCTION prf1 = (void*)p1, prf2 = (void*)p2;
|
||||
return (prf1->FunctionStart > prf2->FunctionStart ? 1 : -1);
|
||||
}
|
||||
|
||||
void
|
||||
GeneratePData(PFILE_INFO File)
|
||||
{
|
||||
DW2CIEFDE *p;
|
||||
DW2FDE Fde;
|
||||
PIMAGE_DATA_DIRECTORY Dir;
|
||||
ULONG i, Offset;
|
||||
void * eh_frame;
|
||||
PRUNTIME_FUNCTION pdata;
|
||||
ULONG xdata_va;
|
||||
char *xdata_p;
|
||||
ULONG cbSize;
|
||||
PIMAGE_SECTION_HEADER pshp, pshx;
|
||||
ULONG FileAlignment;
|
||||
char *pmax;
|
||||
|
||||
FileAlignment = File->OptionalHeader->FileAlignment;
|
||||
|
||||
/* Get pointer to eh_frame section */
|
||||
eh_frame = File->eh_frame.p;
|
||||
g_ehframep = (ULONG)eh_frame;
|
||||
|
||||
/* Get sizes */
|
||||
CountUnwindData(File);
|
||||
// printf("cFuncs = %ld, cUWOPS = %ld, cScopes = %ld\n",
|
||||
// File->cFuncs, File->cUWOP, File->cScopes);
|
||||
|
||||
/* Initialize section header for .pdata */
|
||||
i = File->pdata.idx = File->UsedSections;
|
||||
pshp = File->pdata.psh = &File->NewSectionHeaders[i];
|
||||
memcpy(pshp->Name, ".pdata", 7);
|
||||
pshp->Misc.VirtualSize = (File->cFuncs + 1) * sizeof(RUNTIME_FUNCTION);
|
||||
pshp->VirtualAddress = File->NewSectionHeaders[i - 1].VirtualAddress +
|
||||
File->NewSectionHeaders[i - 1].SizeOfRawData;
|
||||
pshp->SizeOfRawData = ROUND_UP(pshp->Misc.VirtualSize, FileAlignment);
|
||||
pshp->PointerToRawData = File->NewSectionHeaders[i - 1].PointerToRawData +
|
||||
File->NewSectionHeaders[i - 1].SizeOfRawData;
|
||||
pshp->PointerToRelocations = 0;
|
||||
pshp->PointerToLinenumbers = 0;
|
||||
pshp->NumberOfRelocations = 0;
|
||||
pshp->NumberOfLinenumbers = 0;
|
||||
pshp->Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_NOT_PAGED |
|
||||
IMAGE_SCN_CNT_INITIALIZED_DATA;
|
||||
|
||||
/* Allocate .pdata buffer */
|
||||
pdata = File->pdata.p = malloc(pshp->SizeOfRawData);
|
||||
memset(File->pdata.p, 0, pshp->SizeOfRawData);
|
||||
|
||||
/* Init exception data dir */
|
||||
Dir = &File->OptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION];
|
||||
Dir->VirtualAddress = pshp->VirtualAddress;
|
||||
Dir->Size = pshp->Misc.VirtualSize;
|
||||
|
||||
/* Initialize section header for .xdata */
|
||||
File->xdata.idx = File->pdata.idx + 1;
|
||||
pshx = File->xdata.psh = &File->NewSectionHeaders[File->xdata.idx];
|
||||
memcpy(pshx->Name, ".xdata", 7);
|
||||
pshx->Misc.VirtualSize = GetxdataSize(File->cFuncs, File->cUWOP, File->cScopes);
|
||||
pshx->VirtualAddress = pshp->VirtualAddress + pshp->SizeOfRawData;
|
||||
pshx->SizeOfRawData = ROUND_UP(pshx->Misc.VirtualSize, FileAlignment);
|
||||
pshx->PointerToRawData = pshp->PointerToRawData + pshp->SizeOfRawData;
|
||||
pshx->PointerToRelocations = 0;
|
||||
pshx->PointerToLinenumbers = 0;
|
||||
pshx->NumberOfRelocations = 0;
|
||||
pshx->NumberOfLinenumbers = 0;
|
||||
pshx->Characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_NOT_PAGED |
|
||||
IMAGE_SCN_CNT_INITIALIZED_DATA;
|
||||
|
||||
/* Allocate .xdata buffer */
|
||||
File->xdata.p = malloc(pshx->SizeOfRawData);
|
||||
memset(File->xdata.p, 0, pshx->SizeOfRawData);
|
||||
|
||||
i = 0;
|
||||
Offset = File->eh_frame.psh->VirtualAddress;
|
||||
xdata_va = pshx->VirtualAddress;
|
||||
xdata_p = File->xdata.p;
|
||||
pmax = (char*)eh_frame + File->eh_frame.psh->Misc.VirtualSize - 100;
|
||||
|
||||
for (p = eh_frame; p->Length && (char*)p < pmax; p = NextCIE(p))
|
||||
{
|
||||
/* Is this an FDE? */
|
||||
if (p->CiePointer != 0)
|
||||
{
|
||||
DwDecodeFde(&Fde, (char*)p);
|
||||
pdata[i].FunctionStart = Offset + 8 + Fde.PcBegin;
|
||||
pdata[i].FunctionEnd = pdata[i].FunctionStart + Fde.PcRange;
|
||||
pdata[i].UnwindInfo = xdata_va;
|
||||
|
||||
// printf("%ld: RUNTIME_FUNCTION: {0x%lx, 0x%lx, 0x%lx}\n", i, pdata[i].FunctionStart, pdata[i].FunctionEnd, pdata[i].UnwindInfo);
|
||||
|
||||
cbSize = StoreUnwindInfo((void*)xdata_p, &Fde, pdata[i].FunctionStart);
|
||||
xdata_va += cbSize;
|
||||
xdata_p += cbSize;
|
||||
i++;
|
||||
}
|
||||
Offset += 4 + p->Length;
|
||||
}
|
||||
|
||||
/* Sort the RUNTIME_FUNCTIONS */
|
||||
qsort(pdata, i, sizeof(RUNTIME_FUNCTION), CompFunc);
|
||||
|
||||
}
|
||||
|
||||
/** Functions for COFF ********************************************************/
|
||||
|
||||
|
||||
WORD
|
||||
CalculateChecksum(DWORD Start, void *pFile, ULONG cbSize)
|
||||
{
|
||||
WORD *Ptr = pFile;
|
||||
DWORD i;
|
||||
DWORD checksum = Start;
|
||||
|
||||
for (i = 0; i < (cbSize + 1) / sizeof(WORD); i++)
|
||||
{
|
||||
checksum += Ptr[i];
|
||||
checksum = (checksum + (checksum >> 16)) & 0xffff;
|
||||
}
|
||||
|
||||
return checksum ;
|
||||
}
|
||||
|
||||
void
|
||||
WriteOutFile(FILE *handle, PFILE_INFO File)
|
||||
{
|
||||
int ret, Size, Pos = 0;
|
||||
DWORD CheckSum;
|
||||
ULONG i, Alignment;
|
||||
|
||||
Alignment = File->OptionalHeader->FileAlignment;
|
||||
|
||||
/* Update section count */
|
||||
File->FileHeader->NumberOfSections = File->UsedSections + 2; // FIXME!!!
|
||||
|
||||
/* Update SizeOfImage */
|
||||
Size = File->xdata.psh->VirtualAddress
|
||||
+ File->xdata.psh->SizeOfRawData;
|
||||
File->OptionalHeader->SizeOfImage = Size;
|
||||
|
||||
/* Recalculate checksum */
|
||||
CheckSum = CalculateChecksum(0, File->FilePtr, File->HeaderSize);
|
||||
for (i = 0; i < File->AllSections; i++)
|
||||
{
|
||||
if (File->UseSection[i])
|
||||
{
|
||||
Size = File->SectionHeaders[i].SizeOfRawData;
|
||||
if (Size)
|
||||
{
|
||||
void *p;
|
||||
p = File->FilePtr + File->SectionHeaders[i].PointerToRawData;
|
||||
CheckSum = CalculateChecksum(CheckSum, p, Size);
|
||||
}
|
||||
}
|
||||
}
|
||||
Size = File->pdata.psh->Misc.VirtualSize;
|
||||
CheckSum = CalculateChecksum(CheckSum, File->pdata.p, Size);
|
||||
Size = File->xdata.psh->Misc.VirtualSize;
|
||||
CheckSum = CalculateChecksum(CheckSum, File->xdata.p, Size);
|
||||
CheckSum += File->HeaderSize;
|
||||
CheckSum += File->pdata.psh->Misc.VirtualSize;
|
||||
CheckSum += File->xdata.psh->Misc.VirtualSize;
|
||||
File->OptionalHeader->CheckSum = CheckSum;
|
||||
|
||||
/* Write file header */
|
||||
Size = File->HeaderSize;
|
||||
ret = fwrite(File->DosHeader, 1, Size, handle);
|
||||
Pos = Size;
|
||||
|
||||
/* Write Section headers */
|
||||
Size = File->NewSectionHeaderSize;
|
||||
ret = fwrite(File->NewSectionHeaders, 1, Size, handle);
|
||||
Pos += Size;
|
||||
|
||||
/* Fill up to next alignement */
|
||||
Size = ROUND_UP(Pos, Alignment) - Pos;
|
||||
ret = fwrite(File->AlignBuf, 1, Size, handle);
|
||||
Pos += Size;
|
||||
|
||||
/* Write sections */
|
||||
for (i = 0; i < File->AllSections; i++)
|
||||
{
|
||||
if (File->UseSection[i])
|
||||
{
|
||||
void *p;
|
||||
Size = File->SectionHeaders[i].SizeOfRawData;
|
||||
if (Size)
|
||||
{
|
||||
p = File->FilePtr + File->SectionHeaders[i].PointerToRawData;
|
||||
ret = fwrite(p, 1, Size, handle);
|
||||
Pos += Size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Write .pdata section */
|
||||
Size = File->pdata.psh->SizeOfRawData;
|
||||
ret = fwrite(File->pdata.p, 1, Size, handle);
|
||||
Pos += Size;
|
||||
|
||||
/* Write .xdata section */
|
||||
Size = File->xdata.psh->SizeOfRawData;
|
||||
ret = fwrite(File->xdata.p, 1, Size, handle);
|
||||
Pos += Size;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ParsePEHeaders(PFILE_INFO File)
|
||||
{
|
||||
DWORD OldChecksum, Checksum;
|
||||
ULONG Alignment, CurrentPos;
|
||||
int i, j;
|
||||
|
||||
/* Check if MZ header exists */
|
||||
File->DosHeader = (PIMAGE_DOS_HEADER)File->FilePtr;
|
||||
if ((File->DosHeader->e_magic != IMAGE_DOS_MAGIC) ||
|
||||
(File->DosHeader->e_lfanew == 0L))
|
||||
{
|
||||
perror("Input file is not a PE image.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Locate PE file header */
|
||||
File->FileHeader = (PIMAGE_FILE_HEADER)(File->FilePtr +
|
||||
File->DosHeader->e_lfanew + sizeof(ULONG));
|
||||
|
||||
/* Check for x64 image */
|
||||
if (File->FileHeader->Machine != IMAGE_FILE_MACHINE_AMD64)
|
||||
{
|
||||
perror("Input file is not an x64 image.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Locate optional header */
|
||||
File->OptionalHeader = (PIMAGE_OPTIONAL_HEADER64)(File->FileHeader + 1);
|
||||
|
||||
/* Check if checksum is correct */
|
||||
OldChecksum = File->OptionalHeader->CheckSum;
|
||||
File->OptionalHeader->CheckSum = 0;
|
||||
Checksum = CalculateChecksum(0, File->FilePtr, File->cbInFileSize);
|
||||
Checksum += File->cbInFileSize;
|
||||
if ((Checksum & 0xffff) != (OldChecksum & 0xffff))
|
||||
{
|
||||
fprintf(stderr, "Input file has incorrect PE checksum: 0x%lx (calculated: 0x%lx)\n",
|
||||
OldChecksum, Checksum);
|
||||
// return 0;
|
||||
}
|
||||
|
||||
/* Locate PE section headers */
|
||||
File->SectionHeaders = (PIMAGE_SECTION_HEADER)((char*)File->OptionalHeader
|
||||
+ File->FileHeader->SizeOfOptionalHeader);
|
||||
|
||||
File->HeaderSize = File->DosHeader->e_lfanew
|
||||
+ sizeof(ULONG)
|
||||
+ sizeof(IMAGE_FILE_HEADER)
|
||||
+ File->FileHeader->SizeOfOptionalHeader;
|
||||
|
||||
/* Create some shortcuts */
|
||||
File->ImageBase = File->OptionalHeader->ImageBase;
|
||||
File->Symbols = File->FilePtr + File->FileHeader->PointerToSymbolTable;
|
||||
File->Strings = (char*)File->Symbols + File->FileHeader->NumberOfSymbols * 18;
|
||||
|
||||
/* Check section names */
|
||||
File->AllSections = File->FileHeader->NumberOfSections;
|
||||
Alignment = File->OptionalHeader->FileAlignment;
|
||||
File->NewSectionHeaders = malloc((File->AllSections+2) * sizeof(IMAGE_SECTION_HEADER));
|
||||
File->UsedSections = 0;
|
||||
File->eh_frame.idx = -1;
|
||||
|
||||
/* Allocate array of chars, specifying whether to copy the section */
|
||||
File->UseSection = malloc(File->AllSections);
|
||||
|
||||
for (i = 0; i < File->AllSections; i++)
|
||||
{
|
||||
char *pName = (char*)File->SectionHeaders[i].Name;
|
||||
File->UseSection[i] = 1;
|
||||
|
||||
/* Check for long name */
|
||||
if (pName[0] == '/')
|
||||
{
|
||||
unsigned long index = strtoul(pName+1, 0, 10);
|
||||
pName = File->Strings + index;
|
||||
|
||||
// Hack, simply remove all sections with long names
|
||||
File->UseSection[i] = 0;
|
||||
}
|
||||
|
||||
/* Chek if we have the eh_frame section */
|
||||
if (strcmp(pName, ".eh_frame") == 0)
|
||||
{
|
||||
File->eh_frame.psh = &File->SectionHeaders[i];
|
||||
File->eh_frame.idx = i;
|
||||
File->eh_frame.p = File->FilePtr + File->eh_frame.psh->PointerToRawData;
|
||||
}
|
||||
|
||||
/* Increase number of used sections */
|
||||
if (File->UseSection[i])
|
||||
File->UsedSections = i+1;
|
||||
|
||||
}
|
||||
|
||||
/* This is the actual size of the new section headers */
|
||||
File->NewSectionHeaderSize =
|
||||
(File->UsedSections+2) * sizeof(IMAGE_SECTION_HEADER);
|
||||
|
||||
/* Calculate the position to start writing the sections to */
|
||||
CurrentPos = File->HeaderSize + File->NewSectionHeaderSize;
|
||||
CurrentPos = ROUND_UP(CurrentPos, Alignment);
|
||||
|
||||
/* Create new section headers */
|
||||
for (i = 0, j = 0; i < File->UsedSections; i++)
|
||||
{
|
||||
/* Copy section header */
|
||||
File->NewSectionHeaders[j] = File->SectionHeaders[i];
|
||||
|
||||
/* Shall we strip the section? */
|
||||
if (File->UseSection[i] == 0)
|
||||
{
|
||||
/* Make it a bss section */
|
||||
File->NewSectionHeaders[j].PointerToRawData = 0;
|
||||
File->NewSectionHeaders[j].SizeOfRawData = 0;
|
||||
File->NewSectionHeaders[j].Characteristics = 0xC0500080;
|
||||
}
|
||||
|
||||
/* Fix Offset into File */
|
||||
File->NewSectionHeaders[j].PointerToRawData =
|
||||
File->NewSectionHeaders[j].PointerToRawData ? CurrentPos : 0;
|
||||
CurrentPos += File->NewSectionHeaders[j].SizeOfRawData;
|
||||
j++;
|
||||
}
|
||||
|
||||
if (File->eh_frame.idx == -1)
|
||||
{
|
||||
//fprintf(stderr, "No .eh_frame section found\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
char* pszInFile;
|
||||
char* pszOutFile;
|
||||
FILE_INFO File;
|
||||
FILE* outfile;
|
||||
int ret;
|
||||
int arg, argstate = 0;
|
||||
char *SourcePath = NULL;
|
||||
|
||||
for (arg = 1; arg < argc; arg++)
|
||||
{
|
||||
switch (argstate)
|
||||
{
|
||||
default:
|
||||
argstate = -1;
|
||||
break;
|
||||
|
||||
case 0:
|
||||
if (!strcmp(argv[arg], "-s"))
|
||||
{
|
||||
argstate = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
argstate = 2;
|
||||
pszInFile = convert_path(argv[arg]);
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
free(SourcePath);
|
||||
SourcePath = strdup(argv[arg]);
|
||||
argstate = 0;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
pszOutFile = convert_path(argv[arg]);
|
||||
argstate = 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (argstate != 3)
|
||||
{
|
||||
fprintf(stderr, "Usage: rsym [-s <sources>] <input> <output>\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
File.FilePtr = load_file(pszInFile, &File.cbInFileSize);
|
||||
if (!File.FilePtr)
|
||||
{
|
||||
fprintf(stderr, "An error occured loading '%s'\n", pszInFile);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ret = ParsePEHeaders(&File);
|
||||
if (ret != 1)
|
||||
{
|
||||
free(File.FilePtr);
|
||||
exit(ret == -1 ? 1 : 0);
|
||||
}
|
||||
|
||||
File.AlignBuf = malloc(File.OptionalHeader->FileAlignment);
|
||||
memset(File.AlignBuf, 0, File.OptionalHeader->FileAlignment);
|
||||
|
||||
GeneratePData(&File);
|
||||
|
||||
outfile = fopen(pszOutFile, "wb");
|
||||
if (outfile == NULL)
|
||||
{
|
||||
perror("Cannot open output file");
|
||||
free(File.FilePtr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
WriteOutFile(outfile, &File);
|
||||
|
||||
fclose(outfile);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,188 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
//C_ASSERT(sizeof(ULONG) == 4);
|
||||
typedef unsigned char UBYTE;
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
typedef unsigned __int64 ULONG64;
|
||||
#else
|
||||
#include <stdint.h>
|
||||
typedef uint64_t ULONG64;
|
||||
#endif
|
||||
|
||||
|
||||
#define IMAGE_FILE_MACHINE_I386 0x14c
|
||||
#define IMAGE_FILE_MACHINE_AMD64 0x8664
|
||||
#define IMAGE_FILE_MACHINE_ARM64 0xaa64
|
||||
#define IMAGE_DIRECTORY_ENTRY_IMPORT 1
|
||||
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3
|
||||
|
||||
#define UWOP_PUSH_NONVOL 0
|
||||
#define UWOP_ALLOC_LARGE 1
|
||||
#define UWOP_ALLOC_SMALL 2
|
||||
#define UWOP_SET_FPREG 3
|
||||
#define UWOP_SAVE_NONVOL 4
|
||||
#define UWOP_SAVE_NONVOL_FAR 5
|
||||
#define UWOP_SAVE_XMM 6
|
||||
#define UWOP_SAVE_XMM_FAR 7
|
||||
#define UWOP_SAVE_XMM128 8
|
||||
#define UWOP_SAVE_XMM128_FAR 9
|
||||
#define UWOP_PUSH_MACHFRAME 10
|
||||
|
||||
#define REG_RAX 0
|
||||
#define REG_RCX 1
|
||||
#define REG_RDX 2
|
||||
#define REG_RBX 3
|
||||
#define REG_RSP 4
|
||||
#define REG_RBP 5
|
||||
#define REG_RSI 6
|
||||
#define REG_RDI 7
|
||||
#define REG_R8 8
|
||||
#define REG_R9 9
|
||||
#define REG_R10 10
|
||||
#define REG_R11 11
|
||||
#define REG_R12 12
|
||||
#define REG_R13 13
|
||||
#define REG_R14 14
|
||||
#define REG_R15 15
|
||||
|
||||
#define REG_XMM0 0
|
||||
#define REG_XMM1 1
|
||||
#define REG_XMM2 2
|
||||
#define REG_XMM3 3
|
||||
#define REG_XMM4 4
|
||||
#define REG_XMM5 5
|
||||
#define REG_XMM6 6
|
||||
#define REG_XMM7 7
|
||||
#define REG_XMM8 8
|
||||
#define REG_XMM9 9
|
||||
#define REG_XMM10 10
|
||||
#define REG_XMM11 11
|
||||
#define REG_XMM12 12
|
||||
#define REG_XMM13 13
|
||||
#define REG_XMM14 14
|
||||
#define REG_XMM15 15
|
||||
|
||||
|
||||
typedef struct _IMAGE_IMPORT_DESCRIPTOR
|
||||
{
|
||||
union {
|
||||
DWORD Characteristics;
|
||||
DWORD OriginalFirstThunk;
|
||||
};
|
||||
DWORD TimeDateStamp;
|
||||
DWORD ForwarderChain;
|
||||
DWORD Name;
|
||||
DWORD FirstThunk;
|
||||
} IMAGE_IMPORT_DESCRIPTOR, *PIMAGE_IMPORT_DESCRIPTOR;
|
||||
|
||||
typedef struct _IMAGE_THUNK_DATA64
|
||||
{
|
||||
union {
|
||||
ULONGLONG ForwarderString;
|
||||
ULONGLONG Function;
|
||||
ULONGLONG Ordinal;
|
||||
ULONGLONG AddressOfData;
|
||||
} u1;
|
||||
} IMAGE_THUNK_DATA64, *PIMAGE_THUNK_DATA64;
|
||||
|
||||
typedef struct _RUNTIME_FUNCTION
|
||||
{
|
||||
ULONG FunctionStart;
|
||||
ULONG FunctionEnd;
|
||||
ULONG UnwindInfo;
|
||||
} RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;
|
||||
|
||||
typedef union _UNWIND_CODE
|
||||
{
|
||||
struct
|
||||
{
|
||||
UBYTE CodeOffset;
|
||||
UBYTE UnwindOp:4;
|
||||
UBYTE OpInfo:4;
|
||||
};
|
||||
USHORT FrameOffset;
|
||||
} UNWIND_CODE, *PUNWIND_CODE;
|
||||
|
||||
enum
|
||||
{
|
||||
UNW_FLAG_NHANDLER = 0x00,
|
||||
UNW_FLAG_EHANDLER = 0x01,
|
||||
UNW_FLAG_UHANDLER = 0x02,
|
||||
UNW_FLAG_CHAININFO = 0x04
|
||||
};
|
||||
|
||||
typedef struct _UNWIND_INFO
|
||||
{
|
||||
UBYTE Version:3;
|
||||
UBYTE Flags:5;
|
||||
UBYTE SizeOfProlog;
|
||||
UBYTE CountOfCodes;
|
||||
UBYTE FrameRegister:4;
|
||||
UBYTE FrameOffset:4;
|
||||
UNWIND_CODE UnwindCode[1];
|
||||
/* union {
|
||||
OPTIONAL ULONG ExceptionHandler;
|
||||
OPTIONAL ULONG FunctionEntry;
|
||||
};
|
||||
OPTIONAL ULONG ExceptionData[];
|
||||
*/
|
||||
} UNWIND_INFO, *PUNWIND_INFO;
|
||||
|
||||
typedef struct _C_SCOPE_TABLE_ENTRY
|
||||
{
|
||||
ULONG Begin;
|
||||
ULONG End;
|
||||
ULONG Handler;
|
||||
ULONG Target;
|
||||
} C_SCOPE_TABLE_ENTRY, *PC_SCOPE_TABLE_ENTRY;
|
||||
|
||||
typedef struct _C_SCOPE_TABLE
|
||||
{
|
||||
ULONG NumEntries;
|
||||
C_SCOPE_TABLE_ENTRY Entry[1];
|
||||
} C_SCOPE_TABLE, *PC_SCOPE_TABLE;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
IMAGE_SECTION_HEADER *psh;
|
||||
char *pName;
|
||||
void *p;
|
||||
ULONG idx;
|
||||
} SECTION;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char* FilePtr;
|
||||
size_t cbInFileSize;
|
||||
size_t cbNewFileSize;
|
||||
|
||||
/* PE data pointers */
|
||||
PIMAGE_DOS_HEADER DosHeader;
|
||||
PIMAGE_FILE_HEADER FileHeader;
|
||||
PIMAGE_OPTIONAL_HEADER64 OptionalHeader;
|
||||
PIMAGE_SECTION_HEADER SectionHeaders;
|
||||
PIMAGE_SECTION_HEADER NewSectionHeaders;
|
||||
ULONG NewSectionHeaderSize;
|
||||
PIMAGE_BASE_RELOCATION Relocations;
|
||||
void *Symbols;
|
||||
char *Strings;
|
||||
ULONG64 ImageBase;
|
||||
ULONG HeaderSize;
|
||||
char *UseSection;
|
||||
|
||||
/* Sections */
|
||||
ULONG AllSections;
|
||||
ULONG UsedSections;
|
||||
|
||||
SECTION eh_frame;
|
||||
SECTION pdata;
|
||||
SECTION xdata;
|
||||
|
||||
char *AlignBuf;
|
||||
|
||||
ULONG cFuncs;
|
||||
ULONG cUWOP;
|
||||
ULONG cScopes;
|
||||
|
||||
} FILE_INFO, *PFILE_INFO;
|
Loading…
Reference in a new issue