mirror of
https://github.com/SysRay/psOff_public.git
synced 2024-11-27 00:20:54 +00:00
move dll2nids to public
This commit is contained in:
parent
bab845e51b
commit
4358d002bb
@ -56,6 +56,8 @@ link_directories(BEFORE
|
||||
)
|
||||
|
||||
add_subdirectory(tools/logging) # include before link_libraries
|
||||
add_subdirectory(tools/dll2Nids)
|
||||
add_dependencies(dll2Nids third_party)
|
||||
|
||||
link_libraries(
|
||||
logging.lib
|
||||
|
@ -17,6 +17,7 @@ add_compile_definitions(__APICALL_IMPORT)
|
||||
|
||||
FOREACH(subdir ${SUBDIRS})
|
||||
ADD_SUBDIRECTORY(${subdir})
|
||||
add_dependencies(${subdir} dll2Nids)
|
||||
ENDFOREACH()
|
||||
|
||||
install(TARGETS ${SUBDIRS}
|
||||
|
@ -1,6 +1,6 @@
|
||||
function(setupModule _Target)
|
||||
add_custom_command(TARGET ${_Target} POST_BUILD
|
||||
COMMAND ${CMAKE_INSTALL_PREFIX}/development/bin/dll2Nids.exe ${CMAKE_CURRENT_BINARY_DIR}/${_Target}.dll
|
||||
COMMAND $<TARGET_FILE:dll2Nids> ${CMAKE_CURRENT_BINARY_DIR}/${_Target}.dll
|
||||
)
|
||||
add_dependencies(${_Target} logging dll2Nids)
|
||||
install(FILES $<TARGET_PDB_FILE:${_Target}> DESTINATION debug OPTIONAL)
|
||||
|
19
tools/dll2nids/CMakeLists.txt
Normal file
19
tools/dll2nids/CMakeLists.txt
Normal file
@ -0,0 +1,19 @@
|
||||
project(dll2Nids VERSION 0.0.1)
|
||||
|
||||
set(SRC
|
||||
main.cpp
|
||||
)
|
||||
|
||||
add_executable(dll2Nids ${SRC})
|
||||
|
||||
target_include_directories(dll2Nids PRIVATE
|
||||
${CMAKE_SOURCE_DIR}
|
||||
${CMAKE_BINARY_DIR}/third_party/install/include
|
||||
)
|
||||
|
||||
target_link_directories(dll2Nids PRIVATE
|
||||
${CMAKE_BINARY_DIR}/third_party/install/lib
|
||||
)
|
||||
|
||||
add_dependencies(dll2Nids third_party)
|
||||
target_link_libraries(dll2Nids libboost_container)
|
222
tools/dll2nids/main.cpp
Normal file
222
tools/dll2nids/main.cpp
Normal file
@ -0,0 +1,222 @@
|
||||
#include <boost/uuid/detail/sha1.hpp>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <windows.h>
|
||||
|
||||
std::string encode(const uint8_t* in) {
|
||||
std::string out;
|
||||
out.resize(12);
|
||||
|
||||
auto pOut = out.data();
|
||||
|
||||
constexpr const char* tab = {"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-"};
|
||||
|
||||
for (auto n = 8 / 3; n--;) {
|
||||
*pOut++ = tab[(in[0] & 0xfc) >> 2];
|
||||
*pOut++ = tab[((in[0] & 0x03) << 4) + ((in[1] & 0xf0) >> 4)];
|
||||
*pOut++ = tab[((in[2] & 0xc0) >> 6) + ((in[1] & 0x0f) << 2)];
|
||||
*pOut++ = tab[in[2] & 0x3f];
|
||||
in += 3;
|
||||
}
|
||||
|
||||
*pOut++ = tab[(in[0] & 0xfc) >> 2];
|
||||
*pOut++ = tab[((in[0] & 0x03) << 4) + ((in[1] & 0xf0) >> 4)];
|
||||
*pOut++ = tab[(in[1] & 0x0f) << 2];
|
||||
*pOut++ = '=';
|
||||
|
||||
*pOut = '\0';
|
||||
return out;
|
||||
}
|
||||
|
||||
std::string name2nid(std::string_view name) {
|
||||
boost::uuids::detail::sha1 sha1;
|
||||
sha1.process_bytes((unsigned char*)name.data(), name.size());
|
||||
sha1.process_bytes("\x51\x8d\x64\xa6\x35\xde\xd8\xc1\xE6\xB0\x39\xB1\xC3\xE5\x52\x30", 16);
|
||||
|
||||
unsigned hash[5];
|
||||
sha1.get_digest(hash);
|
||||
|
||||
uint64_t const digest = ((uint64_t)hash[0] << 32u) | hash[1];
|
||||
return encode((uint8_t*)&digest);
|
||||
}
|
||||
|
||||
std::string hexId2nid(std::string_view hexId) {
|
||||
union bytes {
|
||||
uint8_t c[8];
|
||||
uint64_t l;
|
||||
} dst, src;
|
||||
|
||||
uint64_t hash = strtoull(hexId.data(), 0, 16);
|
||||
|
||||
src.l = hash;
|
||||
|
||||
// big <-> little conversion
|
||||
dst.c[0] = src.c[7];
|
||||
dst.c[1] = src.c[6];
|
||||
dst.c[2] = src.c[5];
|
||||
dst.c[3] = src.c[4];
|
||||
dst.c[4] = src.c[3];
|
||||
dst.c[5] = src.c[2];
|
||||
dst.c[6] = src.c[1];
|
||||
dst.c[7] = src.c[0];
|
||||
|
||||
return encode(dst.c);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
|
||||
std::ifstream file;
|
||||
file.open(argv[1], std::ios::binary);
|
||||
if (file.fail()) {
|
||||
printf("Couldn't read %s\n", argv[1]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Read DOS HEADER
|
||||
_IMAGE_DOS_HEADER imageDosHeader;
|
||||
if (file.read((char*)&imageDosHeader, sizeof(_IMAGE_DOS_HEADER)).fail()) {
|
||||
printf("Couldn't read dos header\n");
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (imageDosHeader.e_magic != IMAGE_DOS_SIGNATURE) {
|
||||
printf("File has no DOS Header\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Read NT HEADER
|
||||
_IMAGE_NT_HEADERS imageNtHeaders;
|
||||
file.seekg(imageDosHeader.e_lfanew);
|
||||
|
||||
if (file.read((char*)&imageNtHeaders, sizeof(_IMAGE_NT_HEADERS)).fail()) {
|
||||
printf("Couldn't read NT header\n");
|
||||
return -2;
|
||||
}
|
||||
|
||||
// Read sections -> find .rdata base in file
|
||||
int64_t vaddr_rdata = 0;
|
||||
uint64_t paddr_rdata = 0;
|
||||
|
||||
std::vector<uint8_t> rdata;
|
||||
|
||||
auto const numSections = imageNtHeaders.FileHeader.NumberOfSections;
|
||||
|
||||
{
|
||||
int64_t curOffset = imageDosHeader.e_lfanew + sizeof(_IMAGE_NT_HEADERS) + 16;
|
||||
file.seekg(curOffset, std::ios_base::beg);
|
||||
}
|
||||
|
||||
for (size_t n = 0; n < numSections; ++n) {
|
||||
_IMAGE_SECTION_HEADER header;
|
||||
if (file.read((char*)&header, IMAGE_SIZEOF_SECTION_HEADER).fail()) {
|
||||
printf("Couldn't read NT header\n");
|
||||
return -2;
|
||||
}
|
||||
if (std::string((char*)header.Name) == ".rdata") {
|
||||
vaddr_rdata = header.VirtualAddress;
|
||||
paddr_rdata = header.PointerToRawData;
|
||||
|
||||
rdata.resize(header.SizeOfRawData);
|
||||
|
||||
file.seekg(paddr_rdata, std::ios_base::beg);
|
||||
if (file.read((char*)rdata.data(), rdata.size()).fail()) {
|
||||
printf("Couldn't read rdata header\n");
|
||||
return -2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (vaddr_rdata == 0) {
|
||||
printf("Couldn't find .rdata\n");
|
||||
return -2;
|
||||
}
|
||||
// -
|
||||
|
||||
// Additional Header
|
||||
PIMAGE_OPTIONAL_HEADER imageOptionalHeader = (PIMAGE_OPTIONAL_HEADER)&imageNtHeaders.OptionalHeader;
|
||||
PIMAGE_DATA_DIRECTORY imageExportDataDirectory = &(imageOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]);
|
||||
|
||||
PIMAGE_EXPORT_DIRECTORY imageExportDirectory = (PIMAGE_EXPORT_DIRECTORY)(rdata.data() + imageExportDataDirectory->VirtualAddress - vaddr_rdata);
|
||||
|
||||
DWORD numNames = imageExportDirectory->NumberOfNames;
|
||||
PDWORD exportNamePointerTable = (PDWORD)(rdata.data() + imageExportDirectory->AddressOfNames - vaddr_rdata);
|
||||
PDWORD exportAddressTable = (PDWORD)(rdata.data() + imageExportDirectory->AddressOfFunctions - vaddr_rdata);
|
||||
// -
|
||||
|
||||
// ### Read all symbol names, make nids, store with new offset
|
||||
// Read all and change to nids
|
||||
|
||||
std::vector<std::string> symbols(numNames);
|
||||
bool hasModuleName = false;
|
||||
for (size_t n = 0; n < numNames; n++) {
|
||||
auto name = std::string_view((const char*)(rdata.data() + exportNamePointerTable[n] - vaddr_rdata));
|
||||
// Handle mangled name
|
||||
if (name.starts_with('?')) {
|
||||
name = name.substr(1, name.find_first_of('@') - 1);
|
||||
}
|
||||
// -
|
||||
|
||||
if (name.starts_with("sce") || name.starts_with("_sce")) {
|
||||
// Change to nids
|
||||
symbols[n] = name2nid(name);
|
||||
} else if (name.starts_with("__hex_")) {
|
||||
// Change to nids
|
||||
symbols[n] = hexId2nid(name.substr(6));
|
||||
} else if (name.starts_with("__sce_")) {
|
||||
// Change to nids
|
||||
symbols[n] = name2nid(name.substr(6));
|
||||
} else {
|
||||
symbols[n] = std::string(name);
|
||||
if (!hasModuleName && name == "MODULE_NAME") {
|
||||
hasModuleName = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasModuleName) {
|
||||
printf("MODULE_NAME not found\n");
|
||||
return -2;
|
||||
}
|
||||
|
||||
const char* tableEndAddr = 0;
|
||||
{
|
||||
auto name = std::string_view((const char*)(rdata.data() + exportNamePointerTable[numNames - 1] - vaddr_rdata));
|
||||
tableEndAddr = name.data() + name.size();
|
||||
}
|
||||
|
||||
// Store
|
||||
DWORD curOffset = exportNamePointerTable[0] - vaddr_rdata;
|
||||
for (size_t n = 0; n < numNames; n++) {
|
||||
// Create new offsets
|
||||
exportNamePointerTable[n] = curOffset + vaddr_rdata;
|
||||
|
||||
// store name
|
||||
auto pDest = (char*)(rdata.data() + curOffset);
|
||||
memcpy(pDest, symbols[n].data(), 1 + symbols[n].size());
|
||||
curOffset += 1 + symbols[n].size();
|
||||
}
|
||||
|
||||
if ((char*)rdata.data() + curOffset > tableEndAddr) {
|
||||
size_t const diff = ((char*)rdata.data() + curOffset) - tableEndAddr;
|
||||
printf("New Table is > old by %llu\nSimply add a dummy function", diff);
|
||||
return -2;
|
||||
}
|
||||
for (char* begin = (char*)rdata.data() + curOffset; begin < tableEndAddr; ++begin) {
|
||||
*begin = 0;
|
||||
}
|
||||
|
||||
std::fstream outFile;
|
||||
outFile.open(argv[1], std::ios::out | std::ios::in | std::ios::binary);
|
||||
if (outFile.fail()) {
|
||||
printf("Couldn't open file for out, %s\n", argv[1]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
outFile.seekp(paddr_rdata, std::ios_base::beg);
|
||||
if (outFile.write((char*)rdata.data(), rdata.size()).fail()) {
|
||||
printf("Couldn't write data\n");
|
||||
return -2;
|
||||
}
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user