Skip to content

Commit

Permalink
Sources from v1.2.
Browse files Browse the repository at this point in the history
  • Loading branch information
[email protected] committed Oct 12, 2014
1 parent c8c3123 commit 8dc6479
Show file tree
Hide file tree
Showing 8 changed files with 198 additions and 62 deletions.
4 changes: 2 additions & 2 deletions .cproject
Original file line number Diff line number Diff line change
Expand Up @@ -539,15 +539,15 @@
<target name="all" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments/>
<buildTarget>all IDA=C:/usr/IDA/idasdk61/</buildTarget>
<buildTarget>all IDA=C:/usr/IDA/idasdk62/</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
<target name="clean" path="" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments/>
<buildTarget>clean IDA=C:/usr/IDA/idasdk61/</buildTarget>
<buildTarget>clean IDA=C:/usr/IDA/idasdk62/</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
Expand Down
9 changes: 8 additions & 1 deletion docs/readme.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
IDA Pro plugin
Loads a VC/Borland/Dede/GCC/IDA map file into IDA Database.
The ".map" file may be generated during compilation, and contain some of debug info (function names, global variables).

compiled with IDA 6.1 SDK, compiler - GCC 4.5.0
This plugin was compiled with IDA 6.2 SDK, compiler - GCC 4.8.0; it is 32-bit.
IDA SDK required small patch to cooperate with that gcc - it is within src.

See src/LoadMap.cpp for credits, license and changelog.

Installation:
* Copy LoadMAP.plw to IDA plugins folder
* Open any PE/LE file project
* Click Load MAP with Shift to see options

Known issues:
Currently it doesn't understand MAP files with 64-bit offsets - new versions of GCC produce files with such long offsets.
WA for this is to just remove excessive zeros from offsets in MAP file before loading it.
15 changes: 15 additions & 0 deletions idasdk/plugin.gcc.mak.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Fix for ida 6.2 sdk to compile plugins with gcc 4.8
--- plugin.gcc.mak.orig 2011-09-16 19:04:16 +0000
+++ plugin.gcc.mak 2014-10-12 20:16:53 +0000
@@ -18 +18 @@
-L=$(IDAUNIX)lib/gcc.w32/
+L=$(IDAUNIX)lib/x86_win_gcc_32/
@@ -22 +22 @@
-F=obj/gcc.w32/
+F=obj/x86_win_gcc_32/
@@ -35 +35 @@
-CFLAGS=-I$(I) -DWIN32 -D__NT__ -D__IDP__ -mrtd -mno-cygwin $(__CFLAGS)
+CFLAGS=-I$(I) -DWIN32 -D__NT__ -D__IDP__ -m32 $(__CFLAGS)
@@ -41 +41 @@
-LDFLAGS=--def ../plugin.def -Wl,--dll -shared -mno-cygwin $(_LDFLAGS)
+LDFLAGS=--def ../plugin.def -Wl,--dll -shared -m32 $(_LDFLAGS)
55 changes: 31 additions & 24 deletions src/LoadMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
/// Based on the idea of loadmap plugin by Toshiyuki Tega.
/// @author TQN <[email protected]>
/// @author TL <[email protected]>
/// @date 2004.09.11 - 2011.09.13
/// @date 2004.09.11 - 2012.07.18
/// @version 1.2 - 2012.07.18 - Loading GCC MAP files, compiling in IDA 6.2
/// @version 1.1 - 2011.09.13 - Loading Watcom MAP files, compiling in IDA 6.1
/// @version 1.0 - 2004.09.11 - Initial release
/// @par Copying and copyrights:
Expand All @@ -15,16 +16,31 @@
/// the Free Software Foundation; either version 2 of the License, or
/// (at your option) any later version.
////////////////////////////////////////////////////////////////////////////////
#define PLUG_VERSION "1.1"
#define PLUG_VERSION "1.2"

// standard library headers.
#include <cstdio>
// Makes gcc stdlib to not define non-underscored versions of non-ANSI functions (ie memicmp, strlwr)
#define _NO_OLDNAMES
#include <cstring>
#undef _NO_OLDNAMES

// other headers.
#include "MAPReader.h"
#include "stdafx.h"

#define USE_STANDARD_FILE_FUNCTIONS
#define USE_DANGEROUS_FUNCTIONS

// IDA SDK Header Files
#include <ida.hpp>
#include <idp.hpp>
#include <loader.hpp>
#include <bytes.hpp>
#include <name.hpp>
#include <entry.hpp>
#include <fpro.h>

typedef struct _tagPLUGIN_OPTIONS {
bool bNameApply; //< true - apply to name, false - apply to comment
bool bReplace; //< replace the existing name or comment
Expand All @@ -46,29 +62,17 @@ static char g_szLoadMapSection[] = "LoadMap";
static char g_szOptionsKey[] = "Options";
/// @}

////////////////////////////////////////////////////////////////////////////////
/// @brief Changes extension in given file name buffer
/// @return void
/// @author TL
/// @date 2011.08.07
////////////////////////////////////////////////////////////////////////////////
static void pathExtensionSwitch(char * fname, const char * newext, size_t fnbuf_len)
void linearAddressToSymbolAddr(MapFile::MAPSymbol &sym, unsigned long linear_addr)
{
size_t len,extlen;
char * target;
char * mintarget;
len = std::strlen(fname);
target = std::strrchr(fname,'.');
mintarget = std::strpbrk(fname,":\\/");
if ( (target == NULL) || (target <= mintarget) )
target = fname+len;
extlen = std::strlen(newext);
// If end of the buffer
if (target+extlen+1 >= fname+fnbuf_len)
return;
qstrncpy(target, newext, extlen+1);
sym.seg = segs.get_area_num(linear_addr);
segment_t * sseg = getnseg((int) sym.seg);
if (sseg != NULL)
sym.addr = linear_addr - sseg->startEA;
else
sym.addr = -1;
}


////////////////////////////////////////////////////////////////////////////////
/// @brief Output a formatted string to messages window [analog of printf()]
/// only when the verbose flag of plugin's options is true
Expand Down Expand Up @@ -275,7 +279,7 @@ void idaapi run(int /* arg */)
MapFile::ParseResult parsed;
prvsym.seg = sym.seg;
prvsym.addr = sym.addr;
qstrncpy(prvsym.name,sym.name,sizeof(sym.name));
strncpy(prvsym.name,sym.name,sizeof(sym.name));
sym.seg = SREG_NUM;
sym.addr = BADADDR;
sym.name[0] = '\0';
Expand All @@ -294,6 +298,9 @@ void idaapi run(int /* arg */)
case MapFile::WATCOM_MAP:
parsed = parseWatcomSymbolLine(sym,pLine,lineLen,g_minLineLen,numOfSegs);
break;
case MapFile::GCC_MAP:
parsed = parseGccSymbolLine(sym,pLine,lineLen,g_minLineLen,numOfSegs);
break;
}

if (parsed == MapFile::SKIP_LINE)
Expand Down Expand Up @@ -404,7 +411,7 @@ void idaapi run(int /* arg */)
else
{
// Save file name for next askfile_c dialog
qstrncpy(mapFileName, fname, sizeof(mapFileName));
strncpy(mapFileName, fname, sizeof(mapFileName));

// Show the result
msg("Result of loading and parsing the Map file '%s'\n"
Expand Down
131 changes: 110 additions & 21 deletions src/MAPReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <cstring>
#include <cctype>
#include <cassert>
#include <cstdlib>

#include "stdafx.h"

Expand All @@ -37,6 +38,13 @@ const char WATCOM_END_TABLE_HDR[] = "+----------------------+";
const char MSVC_LINE_NUMBER[] = "Line numbers for ";
const char MSVC_FIXUP[] = "FIXUPS: ";
const char MSVC_EXPORTS[] = " Exports";
const char GCC_MEMMAP_START[] = "Linker script and memory map";
const char GCC_MEMMAP_SKIP1[] = ".";
const char GCC_MEMMAP_SKIP2[] = " .";
const char GCC_MEMMAP_SKIP3[] = "*";
const char GCC_MEMMAP_SKIP4[] = " *";
const char GCC_MEMMAP_END[] = "OUTPUT(";
const char GCC_MEMMAP_LOAD[] = "LOAD ";

/// @}

Expand All @@ -51,23 +59,22 @@ const char MSVC_EXPORTS[] = " Exports";
/// @author TQN
/// @date 2004.09.12
////////////////////////////////////////////////////////////////////////////////
MapFile::MAPResult MapFile::openMAP(const char * lpszFileName, char * &lpMapAddr, size_t &dwSize)
MapFile::MAPResult MapFile::openMAP(const char * fileName, char * &mapAddr, size_t &dwSize)
{
// Set default values for output parameters
lpMapAddr = NULL;
mapAddr = NULL;
dwSize = INVALID_FILE_SIZE;

// Validate all input pointer parameters
assert(NULL != lpszFileName);
assert(FALSE == IsBadStringPtr(lpszFileName, (UINT_PTR) -1));
if ((NULL == lpszFileName) || IsBadStringPtr(lpszFileName, (UINT_PTR) -1))
assert(NULL != fileName);
if (NULL == fileName)
{
SetLastError(ERROR_INVALID_PARAMETER);
return WIN32_ERROR;
}

// Open the file
HANDLE hFile = CreateFile(lpszFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
HANDLE hFile = CreateFile(fileName, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (INVALID_HANDLE_VALUE == hFile)
{
Expand All @@ -92,8 +99,8 @@ MapFile::MAPResult MapFile::openMAP(const char * lpszFileName, char * &lpMapAddr
// Mapping creation successful, do not need file handle anymore
WIN32CHECK(CloseHandle(hFile));

lpMapAddr = (LPSTR) MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, dwSize);
if (NULL == lpMapAddr)
mapAddr = (LPSTR) MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, dwSize);
if (NULL == mapAddr)
{
WIN32CHECK(CloseHandle(hMap));
return WIN32_ERROR;
Expand All @@ -102,11 +109,11 @@ MapFile::MAPResult MapFile::openMAP(const char * lpszFileName, char * &lpMapAddr
// Map View successful, do not need the map handle anymore
WIN32CHECK(CloseHandle(hMap));

if (NULL != memchr(lpMapAddr, 0, dwSize))
if (NULL != memchr(mapAddr, 0, dwSize))
{
// File is binary or Unicode file
WIN32CHECK(UnmapViewOfFile(lpMapAddr));
lpMapAddr = NULL;
WIN32CHECK(UnmapViewOfFile(mapAddr));
mapAddr = NULL;
return FILE_BINARY_ERROR;
}

Expand Down Expand Up @@ -188,6 +195,8 @@ MapFile::SectionType MapFile::recognizeSectionStart(const char *pLine, size_t li
return MapFile::BCCL_VAL_MAP;
if (strncasecmp(pLine, WATCOM_MEMMAP_START, lineLen) == 0)
return MapFile::WATCOM_MAP;
if (strncasecmp(pLine, GCC_MEMMAP_START, lineLen) == 0)
return MapFile::GCC_MAP;
return MapFile::NO_SECTION;
}

Expand All @@ -202,14 +211,28 @@ MapFile::SectionType MapFile::recognizeSectionStart(const char *pLine, size_t li
////////////////////////////////////////////////////////////////////////////////
MapFile::SectionType MapFile::recognizeSectionEnd(MapFile::SectionType secType, const char *pLine, size_t lineLen)
{
if (strncmp(pLine, MSVC_LINE_NUMBER, std::strlen(MSVC_LINE_NUMBER)) == 0)
return MapFile::NO_SECTION;
if (strncmp(pLine, MSVC_FIXUP, std::strlen(MSVC_FIXUP)) == 0)
return MapFile::NO_SECTION;
if (strncmp(pLine, MSVC_EXPORTS, std::strlen(MSVC_EXPORTS)) == 0)
return MapFile::NO_SECTION;
if (strncmp(pLine, WATCOM_END_TABLE_HDR, std::strlen(WATCOM_END_TABLE_HDR)) == 0)
return MapFile::NO_SECTION;
switch (secType)
{
case MapFile::MSVC_MAP:
if (strncmp(pLine, MSVC_LINE_NUMBER, std::strlen(MSVC_LINE_NUMBER)) == 0)
return MapFile::NO_SECTION;
if (strncmp(pLine, MSVC_FIXUP, std::strlen(MSVC_FIXUP)) == 0)
return MapFile::NO_SECTION;
if (strncmp(pLine, MSVC_EXPORTS, std::strlen(MSVC_EXPORTS)) == 0)
return MapFile::NO_SECTION;
break;
case MapFile::BCCL_NAM_MAP:
case MapFile::BCCL_VAL_MAP:
break;
case MapFile::WATCOM_MAP:
if (strncmp(pLine, WATCOM_END_TABLE_HDR, std::strlen(WATCOM_END_TABLE_HDR)) == 0)
return MapFile::NO_SECTION;
break;
case MapFile::GCC_MAP:
if (strncmp(pLine, GCC_MEMMAP_END, std::strlen(GCC_MEMMAP_END)) == 0)
return MapFile::NO_SECTION;
break;
}
return secType;
}

Expand Down Expand Up @@ -241,6 +264,7 @@ MapFile::ParseResult MapFile::parseMsSymbolLine(MapFile::MAPSymbol &sym, const c
std::free(dupLine);
return MapFile::COMMENT_LINE;
}
sym.addr = -1;
int ret = sscanf(dupLine, " %04X : %08X %[^\t\n ;]", &sym.seg, &sym.addr, sym.name);
std::free(dupLine);
if (3 != ret)
Expand All @@ -249,7 +273,7 @@ MapFile::ParseResult MapFile::parseMsSymbolLine(MapFile::MAPSymbol &sym, const c
return MapFile::FINISHING_LINE;
}
else if ((0 == sym.seg) || (--sym.seg >= numOfSegs) ||
(BADADDR == sym.addr) || (std::strlen(sym.name) == 0) )
(-1 == sym.addr) || (std::strlen(sym.name) == 0) )
{
return MapFile::INVALID_LINE;
}
Expand Down Expand Up @@ -306,7 +330,72 @@ MapFile::ParseResult MapFile::parseWatcomSymbolLine(MapFile::MAPSymbol &sym, con
return MapFile::FINISHING_LINE;
}
else if ((0 == sym.seg) || (--sym.seg >= numOfSegs) ||
(BADADDR == sym.addr) || (std::strlen(sym.name) == 0) )
(-1 == sym.addr) || (std::strlen(sym.name) == 0) )
{
return MapFile::INVALID_LINE;
}
// Ensure name is NULL terminated
sym.name[MAXNAMELEN] = '\0';
return MapFile::SYMBOL_LINE;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief Reads one entry of GCC-like MAP file.
/// @param sym Target buffer for symbol data.
/// @param pLine Pointer to start of buffer
/// @param lineLen Length of the current line
/// @param minLineLen Minimal accepted length of line
/// @param numOfSegs Number of segments in IDA, used to verify segment number range
/// @return Result of the parsing
/// @author TL
/// @date 2012.07.18
////////////////////////////////////////////////////////////////////////////////
MapFile::ParseResult MapFile::parseGccSymbolLine(MapFile::MAPSymbol &sym, const char *pLine, size_t lineLen, size_t minLineLen, size_t numOfSegs)
{
// Get segment number, address, name, by pass spaces at beginning,
// between ':' character, between address and name
long lineCut = lineLen;
if (lineCut > MAXNAMELEN + minLineLen)
lineCut = MAXNAMELEN + minLineLen;
char * dupLine = (char *)std::malloc(lineCut+1);
strncpy(dupLine,pLine,lineCut);
dupLine[lineCut] = '\0';
if (strncasecmp(dupLine, ";", 1) == 0)
{
strncpy(sym.name,dupLine+1,MAXNAMELEN-1);
sym.name[MAXNAMELEN] = '\0';
std::free(dupLine);
return MapFile::COMMENT_LINE;
}
if ( (strncasecmp(dupLine, GCC_MEMMAP_SKIP1, std::strlen(GCC_MEMMAP_SKIP1)) == 0) ||
(strncasecmp(dupLine, GCC_MEMMAP_SKIP2, std::strlen(GCC_MEMMAP_SKIP2)) == 0) )
{
std::free(dupLine);
return MapFile::SKIP_LINE;
}
if ( (strncasecmp(dupLine, GCC_MEMMAP_SKIP3, std::strlen(GCC_MEMMAP_SKIP3)) == 0) ||
(strncasecmp(dupLine, GCC_MEMMAP_SKIP4, std::strlen(GCC_MEMMAP_SKIP4)) == 0) )
{
std::free(dupLine);
return MapFile::SKIP_LINE;
}
if (strncasecmp(dupLine, GCC_MEMMAP_LOAD, std::strlen(GCC_MEMMAP_LOAD)) == 0)
{
strncpy(sym.name,dupLine,MAXNAMELEN-1);
sym.name[MAXNAMELEN] = '\0';
std::free(dupLine);
return MapFile::COMMENT_LINE;
}
unsigned long linear_addr;
int ret = sscanf(dupLine, " 0x%08X%*c %[^\t\n;]", &linear_addr, sym.name);
std::free(dupLine);
if (2 != ret)
{
// we have parsed to end of value/name symbols table or reached EOF
return MapFile::FINISHING_LINE;
}
linearAddressToSymbolAddr(sym, linear_addr);
if ((sym.seg >= numOfSegs) || (-1 == sym.addr) || (std::strlen(sym.name) == 0) )
{
return MapFile::INVALID_LINE;
}
Expand Down
7 changes: 6 additions & 1 deletion src/MAPReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ typedef enum {
MSVC_MAP,
BCCL_NAM_MAP,
BCCL_VAL_MAP,
WATCOM_MAP
WATCOM_MAP,
GCC_MAP
} SectionType;

typedef enum {
Expand Down Expand Up @@ -59,7 +60,11 @@ MapFile::SectionType recognizeSectionStart(const char *pLine, size_t lineLen);
MapFile::SectionType recognizeSectionEnd(MapFile::SectionType secType, const char *pLine, size_t lineLen);
MapFile::ParseResult parseMsSymbolLine(MapFile::MAPSymbol &sym, const char *pLine, size_t lineLen, size_t minLineLen, size_t numOfSegs);
MapFile::ParseResult parseWatcomSymbolLine(MapFile::MAPSymbol &sym, const char *pLine, size_t lineLen, size_t minLineLen, size_t numOfSegs);
MapFile::ParseResult parseGccSymbolLine(MapFile::MAPSymbol &sym, const char *pLine, size_t lineLen, size_t minLineLen, size_t numOfSegs);

};

// Converts address in linear form into seg:offs, using IDA sections list
void linearAddressToSymbolAddr(MapFile::MAPSymbol &sym, unsigned long linear_addr);

#endif
Loading

0 comments on commit 8dc6479

Please sign in to comment.