mirror of
https://github.com/QuasarApp/pe-parse.git
synced 2025-04-26 12:24:32 +00:00
Squash (#56)
- CMake: Refactor, added more warnings. - Refactor - Added Windows support - Added a missing include file for linux. - Do not set CMAKE_CXX_STANDARD on Windows - Always initialize the stat struct - CMake: update the required version, request C++11, disable GNU extensions - CMake: Add default switch cases, fix GCC warnings. - Prefer assignment from an empty object when initializing
This commit is contained in:
parent
4d34d91333
commit
0d0ca1861c
6
.gitignore
vendored
6
.gitignore
vendored
@ -3,3 +3,9 @@ cmake_install.cmake
|
||||
dump-prog/dump-prog
|
||||
*.swp
|
||||
python/build
|
||||
.idea
|
||||
cmake-build-debug
|
||||
cmake-build-release
|
||||
build
|
||||
.vscode
|
||||
|
||||
|
@ -1,10 +1,13 @@
|
||||
cmake_minimum_required (VERSION 2.8)
|
||||
cmake_minimum_required(VERSION 3.1)
|
||||
project(pe-parse)
|
||||
|
||||
project (pe-parse)
|
||||
set(CMAKE_VERBOSE_MAKEFILE True)
|
||||
if (NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE "RelWithDebInfo")
|
||||
endif ()
|
||||
|
||||
if(UNIX)
|
||||
set(CMAKE_CXX_FLAGS "-std=c++0x")
|
||||
endif(UNIX)
|
||||
include(cmake/compilation_flags.cmake)
|
||||
list(APPEND GLOBAL_CXXFLAGS ${DEFAULT_CXX_FLAGS})
|
||||
|
||||
add_subdirectory(parser-library)
|
||||
add_subdirectory(dump-prog)
|
||||
|
39
cmake/compilation_flags.cmake
Normal file
39
cmake/compilation_flags.cmake
Normal file
@ -0,0 +1,39 @@
|
||||
if (WIN32)
|
||||
list(APPEND DEFAULT_CXX_FLAGS /W4)
|
||||
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
|
||||
list(APPEND DEFAULT_CXX_FLAGS /Zi)
|
||||
endif ()
|
||||
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
|
||||
list(APPEND DEFAULT_CXX_FLAGS /WX)
|
||||
endif ()
|
||||
|
||||
else ()
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
list(APPEND DEFAULT_CXX_FLAGS
|
||||
-fPIC
|
||||
|
||||
-pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization
|
||||
-Wformat=2 -Winit-self -Wlong-long -Wmissing-declarations -Wmissing-include-dirs -Wcomment
|
||||
-Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-conversion
|
||||
-Wsign-promo -Wstrict-overflow=5 -Wswitch-default -Wundef -Werror -Wunused -Wuninitialized
|
||||
-Wno-missing-declarations
|
||||
)
|
||||
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
|
||||
list(APPEND PROJECT_CXXFLAGS -gdwarf-2 -g3)
|
||||
endif ()
|
||||
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
message(STATUS "This is a debug build; enabling -Weverything...")
|
||||
|
||||
list(APPEND PROJECT_CXXFLAGS
|
||||
-Weverything -Wno-c++98-compat -Wno-missing-prototypes
|
||||
-Wno-missing-variable-declarations -Wno-global-constructors
|
||||
-Wno-exit-time-destructors -Wno-padded -Wno-error
|
||||
)
|
||||
endif ()
|
||||
endif ()
|
@ -1,7 +1,6 @@
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../parser-library)
|
||||
|
||||
add_executable( dump-prog
|
||||
dump.cpp )
|
||||
|
||||
target_link_libraries( dump-prog
|
||||
pe-parser-library )
|
||||
cmake_minimum_required(VERSION 3.1)
|
||||
project(dump-prog)
|
||||
|
||||
add_executable(${PROJECT_NAME} dump.cpp)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE pe-parser-library)
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE ${GLOBAL_CXXFLAGS})
|
||||
|
@ -30,53 +30,66 @@ using namespace std;
|
||||
using namespace peparse;
|
||||
|
||||
int printExps(void *N, VA funcAddr, std::string &mod, std::string &func) {
|
||||
cout << "EXP: ";
|
||||
cout << mod;
|
||||
cout << "!";
|
||||
cout << func;
|
||||
cout << ": 0x";
|
||||
cout << to_string<uint32_t>(funcAddr, hex);
|
||||
cout << endl;
|
||||
static_cast<void>(N);
|
||||
|
||||
auto address = static_cast<std::uint32_t>(funcAddr);
|
||||
|
||||
std::cout << "EXP: ";
|
||||
std::cout << mod;
|
||||
std::cout << "!";
|
||||
std::cout << func;
|
||||
std::cout << ": 0x";
|
||||
std::cout << to_string<decltype(address)>(address, hex);
|
||||
std::cout << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int printImports(void *N, VA impAddr, string &modName, string &symName) {
|
||||
cout << "0x" << to_string<uint32_t>(impAddr, hex);
|
||||
cout << " " << modName << "!" << symName;
|
||||
cout << endl;
|
||||
static_cast<void>(N);
|
||||
|
||||
auto address = static_cast<std::uint32_t>(impAddr);
|
||||
|
||||
std::cout << "0x" << to_string<decltype(address)>(address, hex);
|
||||
std::cout << " " << modName << "!" << symName;
|
||||
std::cout << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int printRelocs(void *N, VA relocAddr, reloc_type type) {
|
||||
cout << "TYPE: ";
|
||||
static_cast<void>(N);
|
||||
|
||||
std::cout << "TYPE: ";
|
||||
switch (type) {
|
||||
case ABSOLUTE:
|
||||
cout << "ABSOLUTE";
|
||||
std::cout << "ABSOLUTE";
|
||||
break;
|
||||
case HIGH:
|
||||
cout << "HIGH";
|
||||
std::cout << "HIGH";
|
||||
break;
|
||||
case LOW:
|
||||
cout << "LOW";
|
||||
std::cout << "LOW";
|
||||
break;
|
||||
case HIGHLOW:
|
||||
cout << "HIGHLOW";
|
||||
std::cout << "HIGHLOW";
|
||||
break;
|
||||
case HIGHADJ:
|
||||
cout << "HIGHADJ";
|
||||
std::cout << "HIGHADJ";
|
||||
break;
|
||||
case MIPS_JMPADDR:
|
||||
cout << "MIPS_JMPADDR";
|
||||
std::cout << "MIPS_JMPADDR";
|
||||
break;
|
||||
case MIPS_JMPADDR16:
|
||||
cout << "MIPS_JMPADD16";
|
||||
std::cout << "MIPS_JMPADD16";
|
||||
break;
|
||||
case DIR64:
|
||||
cout << "DIR64";
|
||||
std::cout << "DIR64";
|
||||
break;
|
||||
default:
|
||||
std::cout << "UNKNOWN";
|
||||
break;
|
||||
}
|
||||
|
||||
cout << " VA: 0x" << to_string<VA>(relocAddr, hex) << endl;
|
||||
std::cout << " VA: 0x" << to_string<VA>(relocAddr, hex) << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -88,136 +101,146 @@ int printSymbols(void *N,
|
||||
uint16_t &type,
|
||||
uint8_t &storageClass,
|
||||
uint8_t &numberOfAuxSymbols) {
|
||||
cout << "Symbol Name: " << strName << endl;
|
||||
cout << "Symbol Value: 0x" << to_string<uint32_t>(value, hex) << endl;
|
||||
static_cast<void>(N);
|
||||
|
||||
cout << "Symbol Section Number: ";
|
||||
std::cout << "Symbol Name: " << strName << endl;
|
||||
std::cout << "Symbol Value: 0x" << to_string<uint32_t>(value, hex) << endl;
|
||||
|
||||
std::cout << "Symbol Section Number: ";
|
||||
switch (sectionNumber) {
|
||||
case IMAGE_SYM_UNDEFINED:
|
||||
cout << "UNDEFINED";
|
||||
std::cout << "UNDEFINED";
|
||||
break;
|
||||
case IMAGE_SYM_ABSOLUTE:
|
||||
cout << "ABSOLUTE";
|
||||
std::cout << "ABSOLUTE";
|
||||
break;
|
||||
case IMAGE_SYM_DEBUG:
|
||||
cout << "DEBUG";
|
||||
std::cout << "DEBUG";
|
||||
break;
|
||||
default:
|
||||
cout << sectionNumber;
|
||||
std::cout << sectionNumber;
|
||||
break;
|
||||
}
|
||||
cout << endl;
|
||||
std::cout << endl;
|
||||
|
||||
cout << "Symbol Type: ";
|
||||
std::cout << "Symbol Type: ";
|
||||
switch (type) {
|
||||
case IMAGE_SYM_TYPE_NULL:
|
||||
cout << "NULL";
|
||||
std::cout << "NULL";
|
||||
break;
|
||||
case IMAGE_SYM_TYPE_VOID:
|
||||
cout << "VOID";
|
||||
std::cout << "VOID";
|
||||
break;
|
||||
case IMAGE_SYM_TYPE_CHAR:
|
||||
cout << "CHAR";
|
||||
std::cout << "CHAR";
|
||||
break;
|
||||
case IMAGE_SYM_TYPE_SHORT:
|
||||
cout << "SHORT";
|
||||
std::cout << "SHORT";
|
||||
break;
|
||||
case IMAGE_SYM_TYPE_INT:
|
||||
cout << "INT";
|
||||
std::cout << "INT";
|
||||
break;
|
||||
case IMAGE_SYM_TYPE_LONG:
|
||||
cout << "LONG";
|
||||
std::cout << "LONG";
|
||||
break;
|
||||
case IMAGE_SYM_TYPE_FLOAT:
|
||||
cout << "FLOAT";
|
||||
std::cout << "FLOAT";
|
||||
break;
|
||||
case IMAGE_SYM_TYPE_DOUBLE:
|
||||
cout << "DOUBLE";
|
||||
std::cout << "DOUBLE";
|
||||
break;
|
||||
case IMAGE_SYM_TYPE_STRUCT:
|
||||
cout << "STRUCT";
|
||||
std::cout << "STRUCT";
|
||||
break;
|
||||
case IMAGE_SYM_TYPE_UNION:
|
||||
cout << "UNION";
|
||||
std::cout << "UNION";
|
||||
break;
|
||||
case IMAGE_SYM_TYPE_ENUM:
|
||||
cout << "ENUM";
|
||||
std::cout << "ENUM";
|
||||
break;
|
||||
case IMAGE_SYM_TYPE_MOE:
|
||||
cout << "IMAGE_SYM_TYPE_MOE";
|
||||
std::cout << "IMAGE_SYM_TYPE_MOE";
|
||||
break;
|
||||
case IMAGE_SYM_TYPE_BYTE:
|
||||
cout << "BYTE";
|
||||
std::cout << "BYTE";
|
||||
break;
|
||||
case IMAGE_SYM_TYPE_WORD:
|
||||
cout << "WORD";
|
||||
std::cout << "WORD";
|
||||
break;
|
||||
case IMAGE_SYM_TYPE_UINT:
|
||||
cout << "UINT";
|
||||
std::cout << "UINT";
|
||||
break;
|
||||
case IMAGE_SYM_TYPE_DWORD:
|
||||
cout << "DWORD";
|
||||
std::cout << "DWORD";
|
||||
break;
|
||||
default:
|
||||
std::cout << "UNKNOWN";
|
||||
break;
|
||||
}
|
||||
cout << endl;
|
||||
std::cout << endl;
|
||||
|
||||
cout << "Symbol Storage Class: ";
|
||||
std::cout << "Symbol Storage Class: ";
|
||||
switch (storageClass) {
|
||||
case IMAGE_SYM_CLASS_END_OF_FUNCTION:
|
||||
cout << "FUNCTION";
|
||||
std::cout << "FUNCTION";
|
||||
break;
|
||||
case IMAGE_SYM_CLASS_NULL:
|
||||
cout << "NULL";
|
||||
std::cout << "NULL";
|
||||
break;
|
||||
case IMAGE_SYM_CLASS_AUTOMATIC:
|
||||
cout << "AUTOMATIC";
|
||||
std::cout << "AUTOMATIC";
|
||||
break;
|
||||
case IMAGE_SYM_CLASS_EXTERNAL:
|
||||
cout << "EXTERNAL";
|
||||
std::cout << "EXTERNAL";
|
||||
break;
|
||||
case IMAGE_SYM_CLASS_STATIC:
|
||||
cout << "STATIC";
|
||||
std::cout << "STATIC";
|
||||
break;
|
||||
case IMAGE_SYM_CLASS_REGISTER:
|
||||
cout << "REGISTER";
|
||||
std::cout << "REGISTER";
|
||||
break;
|
||||
case IMAGE_SYM_CLASS_EXTERNAL_DEF:
|
||||
cout << "EXTERNAL DEF";
|
||||
std::cout << "EXTERNAL DEF";
|
||||
break;
|
||||
case IMAGE_SYM_CLASS_LABEL:
|
||||
cout << "LABEL";
|
||||
std::cout << "LABEL";
|
||||
break;
|
||||
case IMAGE_SYM_CLASS_UNDEFINED_LABEL:
|
||||
cout << "UNDEFINED LABEL";
|
||||
std::cout << "UNDEFINED LABEL";
|
||||
break;
|
||||
case IMAGE_SYM_CLASS_MEMBER_OF_STRUCT:
|
||||
cout << "MEMBER OF STRUCT";
|
||||
std::cout << "MEMBER OF STRUCT";
|
||||
break;
|
||||
default:
|
||||
std::cout << "UNKNOWN";
|
||||
break;
|
||||
}
|
||||
cout << endl;
|
||||
std::cout << endl;
|
||||
|
||||
cout << "Symbol Number of Aux Symbols: " << (uint32_t) numberOfAuxSymbols
|
||||
<< endl;
|
||||
std::cout << "Symbol Number of Aux Symbols: "
|
||||
<< static_cast<uint32_t>(numberOfAuxSymbols) << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int printRsrc(void *N, resource r) {
|
||||
static_cast<void>(N);
|
||||
|
||||
if (r.type_str.length())
|
||||
cout << "Type (string): " << r.type_str << endl;
|
||||
std::cout << "Type (string): " << r.type_str << endl;
|
||||
else
|
||||
cout << "Type: 0x" << to_string<uint32_t>(r.type, hex) << endl;
|
||||
std::cout << "Type: 0x" << to_string<uint32_t>(r.type, hex) << endl;
|
||||
if (r.name_str.length())
|
||||
cout << "Name (string): " << r.name_str << endl;
|
||||
std::cout << "Name (string): " << r.name_str << endl;
|
||||
else
|
||||
cout << "Name: 0x" << to_string<uint32_t>(r.name, hex) << endl;
|
||||
std::cout << "Name: 0x" << to_string<uint32_t>(r.name, hex) << endl;
|
||||
if (r.lang_str.length())
|
||||
cout << "Lang (string): " << r.lang_str << endl;
|
||||
std::cout << "Lang (string): " << r.lang_str << endl;
|
||||
else
|
||||
cout << "Lang: 0x" << to_string<uint32_t>(r.lang, hex) << endl;
|
||||
cout << "Codepage: 0x" << to_string<uint32_t>(r.codepage, hex) << endl;
|
||||
cout << "RVA: " << to_string<uint32_t>(r.RVA, dec) << endl;
|
||||
cout << "Size: " << to_string<uint32_t>(r.size, dec) << endl;
|
||||
std::cout << "Lang: 0x" << to_string<uint32_t>(r.lang, hex) << endl;
|
||||
std::cout << "Codepage: 0x" << to_string<uint32_t>(r.codepage, hex) << endl;
|
||||
std::cout << "RVA: " << to_string<uint32_t>(r.RVA, dec) << endl;
|
||||
std::cout << "Size: " << to_string<uint32_t>(r.size, dec) << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -226,28 +249,35 @@ int printSecs(void *N,
|
||||
string &secName,
|
||||
image_section_header s,
|
||||
bounded_buffer *data) {
|
||||
cout << "Sec Name: " << secName << endl;
|
||||
cout << "Sec Base: 0x" << to_string<uint64_t>(secBase, hex) << endl;
|
||||
static_cast<void>(N);
|
||||
static_cast<void>(s);
|
||||
|
||||
std::cout << "Sec Name: " << secName << endl;
|
||||
std::cout << "Sec Base: 0x" << to_string<uint64_t>(secBase, hex) << endl;
|
||||
if (data)
|
||||
cout << "Sec Size: " << to_string<uint64_t>(data->bufLen, dec) << endl;
|
||||
std::cout << "Sec Size: " << to_string<uint64_t>(data->bufLen, dec) << endl;
|
||||
else
|
||||
cout << "Sec Size: 0" << endl;
|
||||
std::cout << "Sec Size: 0" << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define DUMP_FIELD(x) \
|
||||
std::cout << "" #x << ": 0x"; \
|
||||
std::cout << to_string<std::uint32_t>( \
|
||||
static_cast<std::uint32_t>(p->peHeader.nt.x), std::hex) \
|
||||
<< endl;
|
||||
#define DUMP_DEC_FIELD(x) \
|
||||
std::cout << "" #x << ": "; \
|
||||
std::cout << to_string<uint32_t>( \
|
||||
static_cast<std::uint32_t>(p->peHeader.nt.x), std::dec) \
|
||||
<< endl;
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc == 2) {
|
||||
parsed_pe *p = ParsePEFromFile(argv[1]);
|
||||
|
||||
if (p != NULL) {
|
||||
// print out some things
|
||||
#define DUMP_FIELD(x) \
|
||||
cout << "" #x << ": 0x"; \
|
||||
cout << to_string<uint32_t>(p->peHeader.nt.x, hex) << endl;
|
||||
#define DUMP_DEC_FIELD(x) \
|
||||
cout << "" #x << ": "; \
|
||||
cout << to_string<uint32_t>(p->peHeader.nt.x, dec) << endl;
|
||||
|
||||
// print out some things
|
||||
DUMP_FIELD(Signature);
|
||||
DUMP_FIELD(FileHeader.Machine);
|
||||
DUMP_FIELD(FileHeader.NumberOfSections);
|
||||
@ -314,40 +344,40 @@ int main(int argc, char *argv[]) {
|
||||
#undef DUMP_FIELD
|
||||
#undef DUMP_DEC_FIELD
|
||||
|
||||
cout << "Imports: " << endl;
|
||||
std::cout << "Imports: " << endl;
|
||||
IterImpVAString(p, printImports, NULL);
|
||||
cout << "Relocations: " << endl;
|
||||
std::cout << "Relocations: " << endl;
|
||||
IterRelocs(p, printRelocs, NULL);
|
||||
cout << "Symbols (symbol table): " << endl;
|
||||
std::cout << "Symbols (symbol table): " << endl;
|
||||
IterSymbols(p, printSymbols, NULL);
|
||||
cout << "Sections: " << endl;
|
||||
std::cout << "Sections: " << endl;
|
||||
IterSec(p, printSecs, NULL);
|
||||
cout << "Exports: " << endl;
|
||||
std::cout << "Exports: " << endl;
|
||||
IterExpVA(p, printExps, NULL);
|
||||
|
||||
// read the first 8 bytes from the entry point and print them
|
||||
VA entryPoint;
|
||||
if (GetEntryPoint(p, entryPoint)) {
|
||||
cout << "First 8 bytes from entry point (0x";
|
||||
std::cout << "First 8 bytes from entry point (0x";
|
||||
|
||||
cout << to_string<VA>(entryPoint, hex);
|
||||
cout << "):" << endl;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
std::cout << to_string<VA>(entryPoint, hex);
|
||||
std::cout << "):" << endl;
|
||||
for (std::size_t i = 0; i < 8; i++) {
|
||||
::uint8_t b;
|
||||
ReadByteAtVA(p, i + entryPoint, b);
|
||||
cout << " 0x" << to_string<uint32_t>(b, hex);
|
||||
std::cout << " 0x" << to_string<uint32_t>(b, hex);
|
||||
}
|
||||
|
||||
cout << endl;
|
||||
std::cout << endl;
|
||||
}
|
||||
|
||||
cout << "Resources: " << endl;
|
||||
std::cout << "Resources: " << endl;
|
||||
IterRsrc(p, printRsrc, NULL);
|
||||
DestructParsedPE(p);
|
||||
} else {
|
||||
cout << "Error: " << GetPEErr() << " (" << GetPEErrString() << ")"
|
||||
<< endl;
|
||||
cout << "Location: " << GetPEErrLoc() << endl;
|
||||
std::cout << "Error: " << GetPEErr() << " (" << GetPEErrString() << ")"
|
||||
<< endl;
|
||||
std::cout << "Location: " << GetPEErrLoc() << endl;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -1,3 +1,6 @@
|
||||
add_library(pe-parser-library
|
||||
buffer.cpp
|
||||
parse.cpp)
|
||||
cmake_minimum_required(VERSION 3.1)
|
||||
project(pe-parser-library)
|
||||
|
||||
add_library(${PROJECT_NAME} buffer.cpp parse.cpp)
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE ${GLOBAL_CXXFLAGS})
|
||||
|
@ -23,47 +23,52 @@ THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "parse.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <intrin.h>
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
inline uint16_t byteSwapUint16(uint16_t val) {
|
||||
uint16_t a = (val >> 8) & 0x00FFU;
|
||||
uint16_t b = (val << 8) & 0xFF00U;
|
||||
return a | b;
|
||||
inline std::uint16_t byteSwapUint16(std::uint16_t val) {
|
||||
#if defined(_MSC_VER) || defined(_MSC_FULL_VER)
|
||||
return _byteswap_ushort(val);
|
||||
#else
|
||||
return __builtin_bswap16(val);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline uint32_t byteSwapUint32(uint32_t val) {
|
||||
uint32_t a = byteSwapUint16(val >> 16) & 0x0000FFFFU;
|
||||
uint32_t b = ((static_cast<uint32_t>(byteSwapUint16(val))) << 16) & 0xFFFF0000U;
|
||||
return a | b;
|
||||
inline std::uint32_t byteSwapUint32(std::uint32_t val) {
|
||||
#if defined(_MSC_VER) || defined(_MSC_FULL_VER)
|
||||
return _byteswap_ulong(val);
|
||||
#else
|
||||
return __builtin_bswap32(val);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline uint64_t byteSwapUint64(uint64_t val) {
|
||||
uint64_t a = byteSwapUint32(val >> 32) & 0x00000000FFFFFFFFUL;
|
||||
uint64_t b = ((static_cast<uint64_t>(byteSwapUint32(val))) << 32) & 0xFFFFFFFF00000000UL;
|
||||
return a | b;
|
||||
inline uint64_t byteSwapUint64(std::uint64_t val) {
|
||||
#if defined(_MSC_VER) || defined(_MSC_FULL_VER)
|
||||
return _byteswap_uint64(val);
|
||||
#else
|
||||
return __builtin_bswap64(val);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace peparse {
|
||||
|
||||
extern ::uint32_t err;
|
||||
extern ::string err_loc;
|
||||
extern std::uint32_t err;
|
||||
extern std::string err_loc;
|
||||
|
||||
struct buffer_detail {
|
||||
#ifdef WIN32
|
||||
@ -74,7 +79,7 @@ struct buffer_detail {
|
||||
#endif
|
||||
};
|
||||
|
||||
bool readByte(bounded_buffer *b, ::uint32_t offset, ::uint8_t &out) {
|
||||
bool readByte(bounded_buffer *b, std::uint32_t offset, std::uint8_t &out) {
|
||||
if (b == nullptr) {
|
||||
return false;
|
||||
}
|
||||
@ -83,13 +88,13 @@ bool readByte(bounded_buffer *b, ::uint32_t offset, ::uint8_t &out) {
|
||||
return false;
|
||||
}
|
||||
|
||||
::uint8_t *tmp = (b->buf + offset);
|
||||
std::uint8_t *tmp = (b->buf + offset);
|
||||
out = *tmp;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool readWord(bounded_buffer *b, ::uint32_t offset, ::uint16_t &out) {
|
||||
bool readWord(bounded_buffer *b, std::uint32_t offset, std::uint16_t &out) {
|
||||
if (b == nullptr) {
|
||||
return false;
|
||||
}
|
||||
@ -98,7 +103,7 @@ bool readWord(bounded_buffer *b, ::uint32_t offset, ::uint16_t &out) {
|
||||
return false;
|
||||
}
|
||||
|
||||
::uint16_t *tmp = reinterpret_cast<uint16_t *>(b->buf + offset);
|
||||
std::uint16_t *tmp = reinterpret_cast<std::uint16_t *>(b->buf + offset);
|
||||
if (b->swapBytes) {
|
||||
out = byteSwapUint16(*tmp);
|
||||
} else {
|
||||
@ -108,7 +113,7 @@ bool readWord(bounded_buffer *b, ::uint32_t offset, ::uint16_t &out) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool readDword(bounded_buffer *b, ::uint32_t offset, ::uint32_t &out) {
|
||||
bool readDword(bounded_buffer *b, std::uint32_t offset, std::uint32_t &out) {
|
||||
if (b == nullptr) {
|
||||
return false;
|
||||
}
|
||||
@ -117,7 +122,7 @@ bool readDword(bounded_buffer *b, ::uint32_t offset, ::uint32_t &out) {
|
||||
return false;
|
||||
}
|
||||
|
||||
::uint32_t *tmp = reinterpret_cast<uint32_t *>(b->buf + offset);
|
||||
std::uint32_t *tmp = reinterpret_cast<std::uint32_t *>(b->buf + offset);
|
||||
if (b->swapBytes) {
|
||||
out = byteSwapUint32(*tmp);
|
||||
} else {
|
||||
@ -127,7 +132,7 @@ bool readDword(bounded_buffer *b, ::uint32_t offset, ::uint32_t &out) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool readQword(bounded_buffer *b, ::uint32_t offset, ::uint64_t &out) {
|
||||
bool readQword(bounded_buffer *b, std::uint32_t offset, std::uint64_t &out) {
|
||||
if (b == nullptr) {
|
||||
return false;
|
||||
}
|
||||
@ -136,7 +141,7 @@ bool readQword(bounded_buffer *b, ::uint32_t offset, ::uint64_t &out) {
|
||||
return false;
|
||||
}
|
||||
|
||||
::uint64_t *tmp = reinterpret_cast<uint64_t *>(b->buf + offset);
|
||||
std::uint64_t *tmp = reinterpret_cast<std::uint64_t *>(b->buf + offset);
|
||||
if (b->swapBytes) {
|
||||
out = byteSwapUint64(*tmp);
|
||||
} else {
|
||||
@ -178,7 +183,6 @@ bounded_buffer *readFileToFileBuffer(const char *filePath) {
|
||||
|
||||
// make a buffer object
|
||||
bounded_buffer *p = new (std::nothrow) bounded_buffer();
|
||||
|
||||
if (p == nullptr) {
|
||||
PE_ERR(PEERR_MEM);
|
||||
return nullptr;
|
||||
@ -221,7 +225,8 @@ bounded_buffer *readFileToFileBuffer(const char *filePath) {
|
||||
#else
|
||||
p->detail->fd = fd;
|
||||
|
||||
struct stat s = {0};
|
||||
struct stat s;
|
||||
memset(&s, 0, sizeof(struct stat));
|
||||
|
||||
if (fstat(fd, &s) != 0) {
|
||||
close(fd);
|
||||
@ -231,7 +236,12 @@ bounded_buffer *readFileToFileBuffer(const char *filePath) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void *maddr = mmap(nullptr, s.st_size, PROT_READ, MAP_SHARED, fd, 0);
|
||||
void *maddr = mmap(nullptr,
|
||||
static_cast<std::size_t>(s.st_size),
|
||||
PROT_READ,
|
||||
MAP_SHARED,
|
||||
fd,
|
||||
0);
|
||||
|
||||
if (maddr == MAP_FAILED) {
|
||||
close(fd);
|
||||
@ -241,8 +251,8 @@ bounded_buffer *readFileToFileBuffer(const char *filePath) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
p->buf = reinterpret_cast<uint8_t *>(maddr);
|
||||
p->bufLen = s.st_size;
|
||||
p->buf = reinterpret_cast<std::uint8_t *>(maddr);
|
||||
p->bufLen = static_cast<std::uint32_t>(s.st_size);
|
||||
#endif
|
||||
p->copy = false;
|
||||
p->swapBytes = false;
|
||||
@ -251,7 +261,8 @@ bounded_buffer *readFileToFileBuffer(const char *filePath) {
|
||||
}
|
||||
|
||||
// split buffer inclusively from from to to by offset
|
||||
bounded_buffer *splitBuffer(bounded_buffer *b, ::uint32_t from, ::uint32_t to) {
|
||||
bounded_buffer *
|
||||
splitBuffer(bounded_buffer *b, std::uint32_t from, std::uint32_t to) {
|
||||
if (b == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -262,8 +273,7 @@ bounded_buffer *splitBuffer(bounded_buffer *b, ::uint32_t from, ::uint32_t to) {
|
||||
}
|
||||
|
||||
// make a new buffer
|
||||
bounded_buffer *newBuff = new (std::nothrow) bounded_buffer();
|
||||
|
||||
auto newBuff = new (std::nothrow) bounded_buffer();
|
||||
if (newBuff == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -291,16 +301,11 @@ void deleteBuffer(bounded_buffer *b) {
|
||||
#endif
|
||||
}
|
||||
|
||||
if (b->detail != nullptr) {
|
||||
delete b->detail;
|
||||
}
|
||||
|
||||
delete b->detail;
|
||||
delete b;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t bufLen(bounded_buffer *b) {
|
||||
std::uint64_t bufLen(bounded_buffer *b) {
|
||||
return b->bufLen;
|
||||
}
|
||||
} // namespace peparse
|
||||
|
@ -22,15 +22,18 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _NT_HEADERS
|
||||
#define _NT_HEADERS
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#define _offset(t, f) ((std::uint32_t)(ptrdiff_t) & (((t *) 0)->f))
|
||||
#define _offset(t, f) \
|
||||
static_cast<std::uint32_t>( \
|
||||
reinterpret_cast<ptrdiff_t>(&static_cast<t *>(nullptr)->f))
|
||||
|
||||
// need to pack these structure definitions
|
||||
|
||||
// some constant definitions
|
||||
// clang-format off
|
||||
namespace peparse {
|
||||
constexpr std::uint16_t MZ_MAGIC = 0x5A4D;
|
||||
constexpr std::uint32_t NT_MAGIC = 0x00004550;
|
||||
@ -165,7 +168,7 @@ constexpr std::uint16_t IMAGE_SYM_DTYPE_FUNCTION = 2;
|
||||
constexpr std::uint16_t IMAGE_SYM_DTYPE_ARRAY = 3;
|
||||
|
||||
// Symbol table storage classes
|
||||
constexpr std::uint8_t IMAGE_SYM_CLASS_END_OF_FUNCTION = -1;
|
||||
constexpr std::uint8_t IMAGE_SYM_CLASS_END_OF_FUNCTION = static_cast<const std::uint8_t>(-1);
|
||||
constexpr std::uint8_t IMAGE_SYM_CLASS_NULL = 0;
|
||||
constexpr std::uint8_t IMAGE_SYM_CLASS_AUTOMATIC = 1;
|
||||
constexpr std::uint8_t IMAGE_SYM_CLASS_EXTERNAL = 2;
|
||||
@ -192,6 +195,7 @@ constexpr std::uint8_t IMAGE_SYM_CLASS_FILE = 103;
|
||||
constexpr std::uint8_t IMAGE_SYM_CLASS_SECTION = 104;
|
||||
constexpr std::uint8_t IMAGE_SYM_CLASS_WEAK_EXTERNAL = 105;
|
||||
constexpr std::uint8_t IMAGE_SYM_CLASS_CLR_TOKEN = 107;
|
||||
// clang-format on
|
||||
|
||||
struct dos_header {
|
||||
std::uint16_t e_magic;
|
||||
@ -405,5 +409,3 @@ struct reloc_block {
|
||||
std::uint32_t BlockSize;
|
||||
};
|
||||
} // namespace peparse
|
||||
|
||||
#endif
|
||||
|
@ -25,10 +25,11 @@ THE SOFTWARE.
|
||||
#include "parse.h"
|
||||
#include "nt-headers.h"
|
||||
#include "to_string.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
#include <list>
|
||||
#include <stdexcept>
|
||||
#include <string.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -36,7 +37,7 @@ namespace peparse {
|
||||
|
||||
struct section {
|
||||
string sectionName;
|
||||
::uint64_t sectionBase;
|
||||
std::uint64_t sectionBase;
|
||||
bounded_buffer *sectionData;
|
||||
image_section_header sec;
|
||||
};
|
||||
@ -58,7 +59,7 @@ struct reloc {
|
||||
reloc_type type;
|
||||
};
|
||||
|
||||
#define SYMBOL_NAME_OFFSET(sn) ((uint32_t)(sn.data >> 32))
|
||||
#define SYMBOL_NAME_OFFSET(sn) (static_cast<std::uint32_t>(sn.data >> 32))
|
||||
#define SYMBOL_TYPE_HI(x) (x.type >> 8)
|
||||
|
||||
union symbol_name {
|
||||
@ -122,7 +123,7 @@ struct parsed_pe_internal {
|
||||
list<symbol> symbols;
|
||||
};
|
||||
|
||||
::uint32_t err = 0;
|
||||
std::uint32_t err = 0;
|
||||
std::string err_loc;
|
||||
|
||||
static const char *pe_err_str[] = {"None",
|
||||
@ -136,7 +137,7 @@ static const char *pe_err_str[] = {"None",
|
||||
"Unable to stat",
|
||||
"Bad magic"};
|
||||
|
||||
int GetPEErr() {
|
||||
std::uint32_t GetPEErr() {
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -149,15 +150,17 @@ string GetPEErrLoc() {
|
||||
}
|
||||
|
||||
static bool
|
||||
readCString(const bounded_buffer &buffer, ::uint32_t off, string &result) {
|
||||
readCString(const bounded_buffer &buffer, std::uint32_t off, string &result) {
|
||||
if (off < buffer.bufLen) {
|
||||
::uint8_t *p = buffer.buf;
|
||||
::uint32_t n = buffer.bufLen;
|
||||
::uint8_t *b = p + off;
|
||||
::uint8_t *x = std::find(b, p + n, 0);
|
||||
std::uint8_t *p = buffer.buf;
|
||||
std::uint32_t n = buffer.bufLen;
|
||||
std::uint8_t *b = p + off;
|
||||
std::uint8_t *x = std::find(b, p + n, 0);
|
||||
|
||||
if (x == p + n) {
|
||||
return false;
|
||||
}
|
||||
|
||||
result.insert(result.end(), b, x);
|
||||
return true;
|
||||
}
|
||||
@ -190,30 +193,29 @@ void IterRsrc(parsed_pe *pe, iterRsrc cb, void *cbd) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool parse_resource_id(bounded_buffer *data, ::uint32_t id, string &result) {
|
||||
::uint8_t c;
|
||||
::uint16_t len;
|
||||
bool parse_resource_id(bounded_buffer *data, std::uint32_t id, string &result) {
|
||||
std::uint8_t c;
|
||||
std::uint16_t len;
|
||||
|
||||
if (!readWord(data, id, len)) {
|
||||
return false;
|
||||
}
|
||||
id += 2;
|
||||
for (::uint32_t i = 0; i < len * 2; i++) {
|
||||
for (std::uint32_t i = 0; i < len * 2U; i++) {
|
||||
if (!readByte(data, id + i, c)) {
|
||||
return false;
|
||||
}
|
||||
result.push_back((char) c);
|
||||
result.push_back(static_cast<char>(c));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parse_resource_table(bounded_buffer *sectionData,
|
||||
::uint32_t o,
|
||||
::uint32_t virtaddr,
|
||||
::uint32_t depth,
|
||||
std::uint32_t o,
|
||||
std::uint32_t virtaddr,
|
||||
std::uint32_t depth,
|
||||
resource_dir_entry *dirent,
|
||||
list<resource> &rsrcs) {
|
||||
::uint32_t i = 0;
|
||||
resource_dir_table rdt;
|
||||
|
||||
if (sectionData == nullptr) {
|
||||
@ -233,7 +235,9 @@ bool parse_resource_table(bounded_buffer *sectionData,
|
||||
return true; // This is not a hard error. It does happen.
|
||||
}
|
||||
|
||||
for (i = 0; i < rdt.NameEntries + rdt.IDEntries; i++) {
|
||||
for (std::uint32_t i = 0;
|
||||
i < static_cast<std::uint32_t>(rdt.NameEntries + rdt.IDEntries);
|
||||
i++) {
|
||||
resource_dir_entry *rde = dirent;
|
||||
if (dirent == nullptr) {
|
||||
rde = new resource_dir_entry;
|
||||
@ -358,7 +362,8 @@ bool parse_resource_table(bounded_buffer *sectionData,
|
||||
return false;
|
||||
}
|
||||
|
||||
resource rsrc = {};
|
||||
resource rsrc;
|
||||
memset(&rsrc, 0, sizeof(resource));
|
||||
|
||||
rsrc.type_str = rde->type_str;
|
||||
rsrc.name_str = rde->name_str;
|
||||
@ -418,6 +423,7 @@ bool getResources(bounded_buffer *b,
|
||||
bounded_buffer *fileBegin,
|
||||
list<section> secs,
|
||||
list<resource> &rsrcs) {
|
||||
static_cast<void>(fileBegin);
|
||||
|
||||
if (b == nullptr)
|
||||
return false;
|
||||
@ -470,13 +476,13 @@ bool getSections(bounded_buffer *b,
|
||||
// now we have the section header information, so fill in a section
|
||||
// object appropriately
|
||||
section thisSec;
|
||||
for (::uint32_t i = 0; i < NT_SHORT_NAME_LEN; i++) {
|
||||
::uint8_t c = curSec.Name[i];
|
||||
for (::uint32_t charIndex = 0; charIndex < NT_SHORT_NAME_LEN; charIndex++) {
|
||||
::uint8_t c = curSec.Name[charIndex];
|
||||
if (c == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
thisSec.sectionName.push_back((char) c);
|
||||
thisSec.sectionName.push_back(static_cast<char>(c));
|
||||
}
|
||||
|
||||
if (nthdr.OptionalMagic == NT_OPTIONAL_32_MAGIC) {
|
||||
@ -649,33 +655,24 @@ bool readNtHeader(bounded_buffer *b, nt_header_32 &header) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (TEST_MACHINE_CHARACTERISTICS(header,
|
||||
IMAGE_FILE_MACHINE_AMD64,
|
||||
IMAGE_FILE_BYTES_REVERSED_HI) ||
|
||||
TEST_MACHINE_CHARACTERISTICS(header,
|
||||
IMAGE_FILE_MACHINE_ARM,
|
||||
IMAGE_FILE_BYTES_REVERSED_HI) ||
|
||||
TEST_MACHINE_CHARACTERISTICS(header,
|
||||
IMAGE_FILE_MACHINE_ARM64,
|
||||
IMAGE_FILE_BYTES_REVERSED_HI) ||
|
||||
TEST_MACHINE_CHARACTERISTICS(header,
|
||||
IMAGE_FILE_MACHINE_ARMNT,
|
||||
IMAGE_FILE_BYTES_REVERSED_HI) ||
|
||||
TEST_MACHINE_CHARACTERISTICS(header,
|
||||
IMAGE_FILE_MACHINE_I386,
|
||||
IMAGE_FILE_BYTES_REVERSED_HI) ||
|
||||
TEST_MACHINE_CHARACTERISTICS(header,
|
||||
IMAGE_FILE_MACHINE_M32R,
|
||||
IMAGE_FILE_BYTES_REVERSED_HI) ||
|
||||
TEST_MACHINE_CHARACTERISTICS(header,
|
||||
IMAGE_FILE_MACHINE_POWERPC,
|
||||
IMAGE_FILE_BYTES_REVERSED_HI) ||
|
||||
TEST_MACHINE_CHARACTERISTICS(header,
|
||||
IMAGE_FILE_MACHINE_R4000,
|
||||
IMAGE_FILE_BYTES_REVERSED_HI) ||
|
||||
TEST_MACHINE_CHARACTERISTICS(header,
|
||||
IMAGE_FILE_MACHINE_WCEMIPSV2,
|
||||
IMAGE_FILE_BYTES_REVERSED_HI)) {
|
||||
if (TEST_MACHINE_CHARACTERISTICS(
|
||||
header, IMAGE_FILE_MACHINE_AMD64, IMAGE_FILE_BYTES_REVERSED_HI) ||
|
||||
TEST_MACHINE_CHARACTERISTICS(
|
||||
header, IMAGE_FILE_MACHINE_ARM, IMAGE_FILE_BYTES_REVERSED_HI) ||
|
||||
TEST_MACHINE_CHARACTERISTICS(
|
||||
header, IMAGE_FILE_MACHINE_ARM64, IMAGE_FILE_BYTES_REVERSED_HI) ||
|
||||
TEST_MACHINE_CHARACTERISTICS(
|
||||
header, IMAGE_FILE_MACHINE_ARMNT, IMAGE_FILE_BYTES_REVERSED_HI) ||
|
||||
TEST_MACHINE_CHARACTERISTICS(
|
||||
header, IMAGE_FILE_MACHINE_I386, IMAGE_FILE_BYTES_REVERSED_HI) ||
|
||||
TEST_MACHINE_CHARACTERISTICS(
|
||||
header, IMAGE_FILE_MACHINE_M32R, IMAGE_FILE_BYTES_REVERSED_HI) ||
|
||||
TEST_MACHINE_CHARACTERISTICS(
|
||||
header, IMAGE_FILE_MACHINE_POWERPC, IMAGE_FILE_BYTES_REVERSED_HI) ||
|
||||
TEST_MACHINE_CHARACTERISTICS(
|
||||
header, IMAGE_FILE_MACHINE_R4000, IMAGE_FILE_BYTES_REVERSED_HI) ||
|
||||
TEST_MACHINE_CHARACTERISTICS(
|
||||
header, IMAGE_FILE_MACHINE_WCEMIPSV2, IMAGE_FILE_BYTES_REVERSED_HI)) {
|
||||
b->swapBytes = true;
|
||||
}
|
||||
|
||||
@ -817,10 +814,10 @@ bool getExports(parsed_pe *p) {
|
||||
return false;
|
||||
}
|
||||
|
||||
::uint32_t rvaofft = addr - s.sectionBase;
|
||||
auto rvaofft = static_cast<std::uint32_t>(addr - s.sectionBase);
|
||||
|
||||
// get the name of this module
|
||||
::uint32_t nameRva;
|
||||
std::uint32_t nameRva;
|
||||
if (!readDword(s.sectionData,
|
||||
rvaofft + _offset(export_dir_table, NameRVA),
|
||||
nameRva)) {
|
||||
@ -841,14 +838,14 @@ bool getExports(parsed_pe *p) {
|
||||
return false;
|
||||
}
|
||||
|
||||
::uint32_t nameOff = nameVA - nameSec.sectionBase;
|
||||
auto nameOff = static_cast<std::uint32_t>(nameVA - nameSec.sectionBase);
|
||||
string modName;
|
||||
if (!readCString(*nameSec.sectionData, nameOff, modName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// now, get all the named export symbols
|
||||
::uint32_t numNames;
|
||||
std::uint32_t numNames;
|
||||
if (!readDword(s.sectionData,
|
||||
rvaofft + _offset(export_dir_table, NumberOfNamePointers),
|
||||
numNames)) {
|
||||
@ -878,7 +875,8 @@ bool getExports(parsed_pe *p) {
|
||||
return false;
|
||||
}
|
||||
|
||||
::uint32_t namesOff = namesVA - namesSec.sectionBase;
|
||||
auto namesOff =
|
||||
static_cast<std::uint32_t>(namesVA - namesSec.sectionBase);
|
||||
|
||||
// get the EAT section
|
||||
::uint32_t eatRVA;
|
||||
@ -902,7 +900,7 @@ bool getExports(parsed_pe *p) {
|
||||
return false;
|
||||
}
|
||||
|
||||
::uint32_t eatOff = eatVA - eatSec.sectionBase;
|
||||
auto eatOff = static_cast<std::uint32_t>(eatVA - eatSec.sectionBase);
|
||||
|
||||
// get the ordinal base
|
||||
::uint32_t ordinalBase;
|
||||
@ -913,7 +911,7 @@ bool getExports(parsed_pe *p) {
|
||||
}
|
||||
|
||||
// get the ordinal table
|
||||
::uint32_t ordinalTableRVA;
|
||||
std::uint32_t ordinalTableRVA;
|
||||
if (!readDword(s.sectionData,
|
||||
rvaofft + _offset(export_dir_table, OrdinalTableRVA),
|
||||
ordinalTableRVA)) {
|
||||
@ -936,7 +934,8 @@ bool getExports(parsed_pe *p) {
|
||||
return false;
|
||||
}
|
||||
|
||||
::uint32_t ordinalOff = ordinalTableVA - ordinalTableSec.sectionBase;
|
||||
auto ordinalOff = static_cast<std::uint32_t>(ordinalTableVA -
|
||||
ordinalTableSec.sectionBase);
|
||||
|
||||
for (::uint32_t i = 0; i < numNames; i++) {
|
||||
::uint32_t curNameRVA;
|
||||
@ -961,9 +960,10 @@ bool getExports(parsed_pe *p) {
|
||||
return false;
|
||||
}
|
||||
|
||||
::uint32_t curNameOff = curNameVA - curNameSec.sectionBase;
|
||||
auto curNameOff =
|
||||
static_cast<std::uint32_t>(curNameVA - curNameSec.sectionBase);
|
||||
string symName;
|
||||
::uint8_t d;
|
||||
std::uint8_t d;
|
||||
|
||||
do {
|
||||
if (!readByte(curNameSec.sectionData, curNameOff, d)) {
|
||||
@ -974,7 +974,7 @@ bool getExports(parsed_pe *p) {
|
||||
break;
|
||||
}
|
||||
|
||||
symName.push_back(d);
|
||||
symName.push_back(static_cast<char>(d));
|
||||
curNameOff++;
|
||||
} while (true);
|
||||
|
||||
@ -999,7 +999,7 @@ bool getExports(parsed_pe *p) {
|
||||
(symRVA < exportDir.VirtualAddress + exportDir.Size));
|
||||
|
||||
if (!isForwarded) {
|
||||
::uint32_t symVA;
|
||||
VA symVA;
|
||||
if (p->peHeader.nt.OptionalMagic == NT_OPTIONAL_32_MAGIC) {
|
||||
symVA = symRVA + p->peHeader.nt.OptionalHeader.ImageBase;
|
||||
} else if (p->peHeader.nt.OptionalMagic == NT_OPTIONAL_64_MAGIC) {
|
||||
@ -1049,11 +1049,11 @@ bool getRelocations(parsed_pe *p) {
|
||||
return false;
|
||||
}
|
||||
|
||||
::uint32_t rvaofft = vaAddr - d.sectionBase;
|
||||
auto rvaofft = static_cast<std::uint32_t>(vaAddr - d.sectionBase);
|
||||
|
||||
while (rvaofft < relocDir.Size) {
|
||||
::uint32_t pageRva;
|
||||
::uint32_t blockSize;
|
||||
std::uint32_t pageRva;
|
||||
std::uint32_t blockSize;
|
||||
|
||||
if (!readDword(d.sectionData,
|
||||
rvaofft + _offset(reloc_block, PageRVA),
|
||||
@ -1071,7 +1071,7 @@ bool getRelocations(parsed_pe *p) {
|
||||
// including the Page RVA and Block Size fields and the Type/Offset fields
|
||||
// that follow. Therefore we should subtract 8 bytes from BlockSize to
|
||||
// exclude the Page RVA and Block Size fields.
|
||||
::uint32_t entryCount = (blockSize - 8) / sizeof(::uint16_t);
|
||||
std::uint32_t entryCount = (blockSize - 8) / sizeof(std::uint16_t);
|
||||
|
||||
// Skip the Page RVA and Block Size fields
|
||||
rvaofft += sizeof(reloc_block);
|
||||
@ -1092,7 +1092,7 @@ bool getRelocations(parsed_pe *p) {
|
||||
offset = entry & ~0xf000;
|
||||
|
||||
// Produce the VA of the relocation
|
||||
::uint32_t relocVA;
|
||||
VA relocVA;
|
||||
if (p->peHeader.nt.OptionalMagic == NT_OPTIONAL_32_MAGIC) {
|
||||
relocVA = pageRva + offset + p->peHeader.nt.OptionalHeader.ImageBase;
|
||||
} else if (p->peHeader.nt.OptionalMagic == NT_OPTIONAL_64_MAGIC) {
|
||||
@ -1106,7 +1106,7 @@ bool getRelocations(parsed_pe *p) {
|
||||
reloc r;
|
||||
|
||||
r.shiftedAddr = relocVA;
|
||||
r.type = (reloc_type) type;
|
||||
r.type = static_cast<reloc_type>(type);
|
||||
p->internal->relocs.push_back(r);
|
||||
|
||||
entryCount--;
|
||||
@ -1146,10 +1146,14 @@ bool getImports(parsed_pe *p) {
|
||||
}
|
||||
|
||||
// get import directory from this section
|
||||
::uint32_t offt = addr - c.sectionBase;
|
||||
auto offt = static_cast<std::uint32_t>(addr - c.sectionBase);
|
||||
|
||||
import_dir_entry emptyEnt;
|
||||
memset(&emptyEnt, 0, sizeof(import_dir_entry));
|
||||
|
||||
do {
|
||||
// read each directory entry out
|
||||
import_dir_entry curEnt;
|
||||
import_dir_entry curEnt = emptyEnt;
|
||||
|
||||
READ_DWORD(c.sectionData, offt, curEnt, LookupTableRVA);
|
||||
READ_DWORD(c.sectionData, offt, curEnt, TimeStamp);
|
||||
@ -1178,7 +1182,7 @@ bool getImports(parsed_pe *p) {
|
||||
return false;
|
||||
}
|
||||
|
||||
::uint32_t nameOff = name - nameSec.sectionBase;
|
||||
auto nameOff = static_cast<std::uint32_t>(name - nameSec.sectionBase);
|
||||
string modName;
|
||||
if (!readCString(*nameSec.sectionData, nameOff, modName)) {
|
||||
return false;
|
||||
@ -1216,7 +1220,8 @@ bool getImports(parsed_pe *p) {
|
||||
return false;
|
||||
}
|
||||
|
||||
::uint64_t lookupOff = lookupVA - lookupSec.sectionBase;
|
||||
auto lookupOff =
|
||||
static_cast<std::uint32_t>(lookupVA - lookupSec.sectionBase);
|
||||
::uint32_t offInTable = 0;
|
||||
do {
|
||||
VA valVA = 0;
|
||||
@ -1257,21 +1262,21 @@ bool getImports(parsed_pe *p) {
|
||||
return false;
|
||||
}
|
||||
|
||||
::uint32_t nameOff = valVA - symNameSec.sectionBase;
|
||||
nameOff += sizeof(::uint16_t);
|
||||
std::uint32_t nameOffset =
|
||||
static_cast<std::uint32_t>(valVA - symNameSec.sectionBase) +
|
||||
sizeof(::uint16_t);
|
||||
do {
|
||||
::uint8_t d;
|
||||
|
||||
if (!readByte(symNameSec.sectionData, nameOff, d)) {
|
||||
std::uint8_t chr;
|
||||
if (!readByte(symNameSec.sectionData, nameOffset, chr)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (d == 0) {
|
||||
if (chr == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
symName.push_back(d);
|
||||
nameOff++;
|
||||
symName.push_back(static_cast<char>(chr));
|
||||
nameOffset++;
|
||||
} while (true);
|
||||
|
||||
// okay now we know the pair... add it
|
||||
@ -1365,12 +1370,12 @@ bool getSymbolTable(parsed_pe *p) {
|
||||
if (ch == 0u) {
|
||||
break;
|
||||
}
|
||||
sym.strName.push_back((char) ch);
|
||||
sym.strName.push_back(static_cast<char>(ch));
|
||||
strOffset += sizeof(uint8_t);
|
||||
}
|
||||
} else {
|
||||
for (uint8_t n = 0; n < NT_SHORT_NAME_LEN; n++) {
|
||||
sym.strName.push_back((char) (sym.name.shortName[n]));
|
||||
sym.strName.push_back(static_cast<char>(sym.name.shortName[n]));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1390,7 +1395,7 @@ bool getSymbolTable(parsed_pe *p) {
|
||||
PE_ERR(PEERR_MAGIC);
|
||||
return false;
|
||||
}
|
||||
sym.sectionNumber = (int16_t) secNum;
|
||||
sym.sectionNumber = static_cast<int16_t>(secNum);
|
||||
|
||||
offset += sizeof(uint16_t);
|
||||
|
||||
@ -1537,7 +1542,7 @@ bool getSymbolTable(parsed_pe *p) {
|
||||
PE_ERR(PEERR_MAGIC);
|
||||
return false;
|
||||
}
|
||||
asym.strFilename.push_back((char) asym.filename[j]);
|
||||
asym.strFilename.push_back(static_cast<char>(asym.filename[j]));
|
||||
}
|
||||
|
||||
// Save the record
|
||||
@ -1805,8 +1810,7 @@ bool ReadByteAtVA(parsed_pe *pe, VA v, ::uint8_t &b) {
|
||||
return false;
|
||||
}
|
||||
|
||||
::uint32_t off = v - s.sectionBase;
|
||||
|
||||
auto off = static_cast<std::uint32_t>(v - s.sectionBase);
|
||||
return readByte(s.sectionData, off, b);
|
||||
}
|
||||
|
||||
|
@ -22,8 +22,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _PARSE_H
|
||||
#define _PARSE_H
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
@ -34,10 +34,10 @@ THE SOFTWARE.
|
||||
#define __typeof__(x) std::remove_reference < decltype(x) > ::type
|
||||
#endif
|
||||
|
||||
#define PE_ERR(x) \
|
||||
err = (pe_err) x; \
|
||||
err_loc.assign(__func__); \
|
||||
err_loc += ":" + to_string<std::uint32_t>(__LINE__, dec);
|
||||
#define PE_ERR(x) \
|
||||
err = static_cast<pe_err>(x); \
|
||||
err_loc.assign(__func__); \
|
||||
err_loc += ":" + to_string<std::uint32_t>(__LINE__, std::dec);
|
||||
|
||||
#define READ_WORD(b, o, inst, member) \
|
||||
if (!readWord(b, o + _offset(__typeof__(inst), member), inst.member)) { \
|
||||
@ -57,25 +57,12 @@ THE SOFTWARE.
|
||||
return false; \
|
||||
}
|
||||
|
||||
#define READ_DWORD_PTR(b, o, inst, member) \
|
||||
if (!readDword(b, o + _offset(__typeof__(*inst), member), inst->member)) { \
|
||||
PE_ERR(PEERR_READ); \
|
||||
return false; \
|
||||
}
|
||||
|
||||
#define READ_BYTE(b, o, inst, member) \
|
||||
if (!readByte(b, o + _offset(__typeof__(inst), member), inst.member)) { \
|
||||
PE_ERR(PEERR_READ); \
|
||||
return false; \
|
||||
}
|
||||
|
||||
/* This variant returns NULL instead of false. */
|
||||
#define READ_DWORD_NULL(b, o, inst, member) \
|
||||
if (!readDword(b, o + _offset(__typeof__(inst), member), inst.member)) { \
|
||||
PE_ERR(PEERR_READ); \
|
||||
return NULL; \
|
||||
}
|
||||
|
||||
#define TEST_MACHINE_CHARACTERISTICS(h, m, ch) \
|
||||
((h.FileHeader.Machine == m) && (h.FileHeader.Characteristics & ch))
|
||||
|
||||
@ -158,7 +145,9 @@ uint64_t bufLen(bounded_buffer *b);
|
||||
|
||||
struct parsed_pe_internal;
|
||||
|
||||
typedef struct _pe_header { nt_header_32 nt; } pe_header;
|
||||
typedef struct _pe_header {
|
||||
nt_header_32 nt;
|
||||
} pe_header;
|
||||
|
||||
typedef struct _parsed_pe {
|
||||
bounded_buffer *fileBuffer;
|
||||
@ -167,7 +156,7 @@ typedef struct _parsed_pe {
|
||||
} parsed_pe;
|
||||
|
||||
// get parser error status as integer
|
||||
int GetPEErr();
|
||||
std::uint32_t GetPEErr();
|
||||
|
||||
// get parser error status as string
|
||||
std::string GetPEErrString();
|
||||
@ -196,11 +185,11 @@ void IterRelocs(parsed_pe *pe, iterReloc cb, void *cbd);
|
||||
// Iterate over symbols (symbol table) in the PE file
|
||||
typedef int (*iterSymbol)(void *,
|
||||
std::string &,
|
||||
uint32_t &,
|
||||
int16_t &,
|
||||
uint16_t &,
|
||||
uint8_t &,
|
||||
uint8_t &);
|
||||
std::uint32_t &,
|
||||
std::int16_t &,
|
||||
std::uint16_t &,
|
||||
std::uint8_t &,
|
||||
std::uint8_t &);
|
||||
void IterSymbols(parsed_pe *pe, iterSymbol cb, void *cbd);
|
||||
|
||||
// iterate over the exports
|
||||
@ -218,5 +207,3 @@ bool ReadByteAtVA(parsed_pe *pe, VA v, std::uint8_t &b);
|
||||
// get entry point into PE
|
||||
bool GetEntryPoint(parsed_pe *pe, VA &v);
|
||||
} // namespace peparse
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
#ifndef _TO_STRING_H
|
||||
#define _TO_STRING_H
|
||||
#pragma once
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace peparse {
|
||||
@ -9,5 +9,4 @@ static std::string to_string(T t, std::ios_base &(*f)(std::ios_base &) ) {
|
||||
oss << f << t;
|
||||
return oss.str();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} // namespace peparse
|
||||
|
Loading…
x
Reference in New Issue
Block a user