#include <string.h>
#include <stdlib.h>
-#define NULL ((void*)0)
-
#define IMAGE_DOS_MAGIC 0x5a4d
#define IMAGE_PE_MAGIC 0x00004550
unsigned long StabstrLength;
} SYMBOLFILE_HEADER, *PSYMBOLFILE_HEADER;
+typedef struct _STAB_ENTRY {
+ unsigned long n_strx; /* index into string table of name */
+ unsigned char n_type; /* type of symbol */
+ unsigned char n_other; /* misc info (usually empty) */
+ unsigned short n_desc; /* description field */
+ unsigned long n_value; /* value of symbol */
+} STAB_ENTRY, *PSTAB_ENTRY;
+
+#define N_FUN 0x24
+#define N_SLINE 0x44
+#define N_SO 0x64
+
+typedef struct
+{
+ unsigned long OldOffset;
+ unsigned long NewOffset;
+ char* Name;
+ unsigned long Length;
+} STR_ENTRY, *PSTR_ENTRY;
char* convert_path(char* origpath)
{
char* newpath;
int i;
-
+
newpath = strdup(origpath);
-
+
i = 0;
while (newpath[i] != 0)
{
{
newpath[i] = '\\';
}
-#endif
-#endif
+#endif
+#endif
i++;
}
return(newpath);
SYMBOLFILE_HEADER SymbolFileHeader;
IMAGE_DOS_HEADER PEDosHeader;
IMAGE_FILE_HEADER PEFileHeader;
+ PIMAGE_OPTIONAL_HEADER PEOptHeader;
PIMAGE_SECTION_HEADER PESectionHeaders;
+ ULONG ImageBase;
PVOID SymbolsBase;
ULONG SymbolsLength;
PVOID SymbolStringsBase;
char* path2;
FILE* in;
FILE* out;
- char* buf;
int n_in;
int n_out;
-
+ PSTAB_ENTRY StabEntry;
+ ULONG Count;
+ ULONG i;
+ ULONG SymbolsCount;
+ PSTR_ENTRY StrEntry;
+ ULONG StrCount;
+ ULONG j;
+
if (argc != 3)
{
fprintf(stderr, "Too many arguments\n");
exit(1);
}
-
+
path1 = convert_path(argv[1]);
path2 = convert_path(argv[2]);
-
+
in = fopen(path1, "rb");
if (in == NULL)
{
fseek(in, PEDosHeader.e_lfanew + sizeof(ULONG), SEEK_SET);
n_in = fread(&PEFileHeader, 1, sizeof(PEFileHeader), in);
+ /* Read optional header */
+ PEOptHeader = malloc(PEFileHeader.SizeOfOptionalHeader);
+ fread ( PEOptHeader, 1, PEFileHeader.SizeOfOptionalHeader, in );
+ ImageBase = PEOptHeader->ImageBase;
+
/* Read PE section headers */
PESectionHeaders = malloc(PEFileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER));
fseek(in, PEDosHeader.e_lfanew + sizeof(ULONG) + sizeof(IMAGE_FILE_HEADER)
if ((strncmp(PESectionHeaders[Idx].Name, ".stab", 5) == 0)
&& (PESectionHeaders[Idx].Name[5] == 0))
{
- //printf(".stab section found. Size %d\n",
+ //printf(".stab section found. Size %d\n",
// PESectionHeaders[Idx].SizeOfRawData);
SymbolsLength = PESectionHeaders[Idx].SizeOfRawData;
if (strncmp(PESectionHeaders[Idx].Name, ".stabstr", 8) == 0)
{
- //printf(".stabstr section found. Size %d\n",
+ //printf(".stabstr section found. Size %d\n",
// PESectionHeaders[Idx].SizeOfRawData);
SymbolStringsLength = PESectionHeaders[Idx].SizeOfRawData;
}
}
+ StabEntry = SymbolsBase;
+ SymbolsCount = SymbolsLength / sizeof(STAB_ENTRY);
+ Count = 0;
+
+ for (i = 0; i < SymbolsCount; i++)
+ {
+ switch ( StabEntry[i].n_type )
+ {
+ case N_FUN:
+ if ( StabEntry[i].n_desc == 0 ) // line # 0 isn't valid
+ continue;
+ break;
+ case N_SLINE:
+ break;
+ case N_SO:
+ break;
+ default:
+ continue;
+ }
+ memmove(&StabEntry[Count], &StabEntry[i], sizeof(STAB_ENTRY));
+ if ( StabEntry[Count].n_value >= ImageBase )
+ StabEntry[Count].n_value -= ImageBase;
+ Count++;
+ }
+
+ StrEntry = malloc(sizeof(STR_ENTRY) * Count);
+ StrCount = 0;
+
+ for (i = 0; i < Count; i++)
+ {
+ for (j = 0; j < StrCount; j++)
+ {
+ if (StabEntry[i].n_strx == StrEntry[j].OldOffset)
+ {
+ StabEntry[i].n_strx = StrEntry[j].NewOffset;
+ break;
+ }
+ }
+ if (j >= StrCount)
+ {
+ StrEntry[StrCount].OldOffset = StabEntry[i].n_strx;
+ StrEntry[StrCount].Name = (char*)SymbolStringsBase + StrEntry[StrCount].OldOffset;
+ StrEntry[StrCount].Length = strlen(StrEntry[StrCount].Name) + 1;
+ if (StrCount == 0)
+ {
+ StrEntry[StrCount].NewOffset = 0;
+ }
+ else
+ {
+ StrEntry[StrCount].NewOffset = StrEntry[StrCount-1].NewOffset + StrEntry[StrCount-1].Length;
+ }
+ StabEntry[i].n_strx = StrEntry[StrCount].NewOffset;
+ StrCount++;
+ }
+ }
+
SymbolFileHeader.StabsOffset = sizeof(SYMBOLFILE_HEADER);
- SymbolFileHeader.StabsLength = SymbolsLength;
- SymbolFileHeader.StabstrOffset = SymbolFileHeader.StabsOffset + SymbolsLength;
- SymbolFileHeader.StabstrLength = SymbolStringsLength;
+ SymbolFileHeader.StabsLength = Count * sizeof(STAB_ENTRY);
+ SymbolFileHeader.StabstrOffset = SymbolFileHeader.StabsOffset + SymbolFileHeader.StabsLength;
+ SymbolFileHeader.StabstrLength = StrEntry[StrCount-1].NewOffset + StrEntry[StrCount-1].Length;
n_out = fwrite(&SymbolFileHeader, 1, sizeof(SYMBOLFILE_HEADER), out);
- n_out = fwrite(SymbolsBase, 1, SymbolsLength, out);
- n_out = fwrite(SymbolStringsBase, 1, SymbolStringsLength, out);
+ n_out = fwrite(SymbolsBase, 1, SymbolFileHeader.StabsLength, out);
+ for (i = 0; i < StrCount; i++)
+ {
+ fwrite(StrEntry[i].Name, 1, StrEntry[i].Length, out);
+ }
+ fclose(out);
exit(0);
}