mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-11 16:46:16 +00:00
add optional apiset dump tool
This commit is contained in:
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -36,7 +36,7 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Dump Registry
|
||||
run: src/grab-registry.bat
|
||||
run: src/tools/grab-registry.bat
|
||||
|
||||
- name: Upload Artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
|
||||
@@ -87,7 +87,7 @@ cmake --workflow --preset=release
|
||||
## Dumping the Registry
|
||||
|
||||
The emulator needs a registry dump to run, otherwise it will print `Bad hive file` errors.
|
||||
You can create one by running the <a href="./src/grab-registry.bat">src/grab-registry.bat</a> script as administrator.
|
||||
You can create one by running the <a href="./src/tools/grab-registry.bat">src/tools/grab-registry.bat</a> script as administrator.
|
||||
This will create a `registry` folder that needs to be placed in the working directory of the emulator.
|
||||
|
||||
## Running Tests
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
add_subdirectory(common)
|
||||
add_subdirectory(tools)
|
||||
add_subdirectory(emulator)
|
||||
add_subdirectory(unicorn-emulator)
|
||||
add_subdirectory(windows-emulator)
|
||||
|
||||
4
src/tools/CMakeLists.txt
Normal file
4
src/tools/CMakeLists.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
if(WIN32)
|
||||
add_subdirectory(dump-apiset)
|
||||
endif()
|
||||
|
||||
17
src/tools/dump-apiset/CMakeLists.txt
Normal file
17
src/tools/dump-apiset/CMakeLists.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
file(GLOB_RECURSE SRC_FILES CONFIGURE_DEPENDS
|
||||
*.cpp
|
||||
*.hpp
|
||||
*.rc
|
||||
)
|
||||
|
||||
list(SORT SRC_FILES)
|
||||
|
||||
add_executable(dump-apiset ${SRC_FILES})
|
||||
|
||||
momo_assign_source_group(${SRC_FILES})
|
||||
|
||||
target_link_libraries(dump-apiset PRIVATE
|
||||
emulator-common
|
||||
)
|
||||
|
||||
momo_strip_target(dump-apiset)
|
||||
118
src/tools/dump-apiset/dump-apiset.cpp
Normal file
118
src/tools/dump-apiset/dump-apiset.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
#include <cstdio>
|
||||
#include "platform/platform.hpp"
|
||||
#include "utils/compression.hpp"
|
||||
#include "utils/io.hpp"
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
void print_apiset(PAPI_SET_NAMESPACE apiSetMap);
|
||||
void create_header_file(const std::vector<uint8_t>& data);
|
||||
|
||||
__forceinline PVOID GetCurrentProcessPeb()
|
||||
{
|
||||
#ifdef _WIN64
|
||||
return (PVOID)__readgsqword(0x60);
|
||||
#else
|
||||
return (PVOID)__readfsdword(0x30);
|
||||
#endif
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
printf("Dump API-SET\n");
|
||||
printf("------------\n\n");
|
||||
|
||||
const auto peb = (PPEB64)GetCurrentProcessPeb();
|
||||
const auto apiSetMap = (PAPI_SET_NAMESPACE)(peb->ApiSetMap);
|
||||
|
||||
printf("APISET: 0x%p\n", apiSetMap);
|
||||
printf("Version: %d\n", apiSetMap->Version);
|
||||
printf("Size: %08X\n", apiSetMap->Size);
|
||||
printf("Flags: %08X\n", apiSetMap->Flags);
|
||||
printf("Count: %d\n", apiSetMap->Count);
|
||||
printf("EntryOffset: %08X\n", apiSetMap->EntryOffset);
|
||||
printf("HashOffset: %08X\n", apiSetMap->HashOffset);
|
||||
printf("HashFactor: %08X\n", apiSetMap->HashFactor);
|
||||
// print_apiset(apiSetMap);
|
||||
|
||||
// Compress the API-SET binary blob
|
||||
const auto* dataPtr = reinterpret_cast<const uint8_t*>(apiSetMap);
|
||||
std::vector<uint8_t> buffer(dataPtr, dataPtr + apiSetMap->Size);
|
||||
auto compressed = utils::compression::zlib::compress(buffer);
|
||||
if (compressed.empty())
|
||||
{
|
||||
printf("Failed to compress API-SET\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Dump the API-SET binary blob to disk
|
||||
utils::io::write_file("api-set.bin", compressed, false);
|
||||
printf("\nWrote API-SET to api-set.bin\n");
|
||||
// create_header_file(compressed);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void print_apiset(PAPI_SET_NAMESPACE apiSetMap)
|
||||
{
|
||||
for (ULONG i = 0; i < apiSetMap->Count; i++)
|
||||
{
|
||||
auto entry = (PAPI_SET_NAMESPACE_ENTRY)((ULONG_PTR)apiSetMap + apiSetMap->EntryOffset +
|
||||
i * sizeof(API_SET_NAMESPACE_ENTRY));
|
||||
// printf(" Flags: %08X\n", entry->Flags);
|
||||
// printf(" NameOffset: %08X\n", entry->NameOffset);
|
||||
// printf(" NameLength: %08X\n", entry->NameLength);
|
||||
// printf(" HashedLength: %08X\n", entry->HashedLength);
|
||||
// printf(" ValueOffset: %08X\n", entry->ValueOffset);
|
||||
// printf(" ValueCount: %08X\n", entry->ValueCount);
|
||||
|
||||
std::wstring name((wchar_t*)((ULONG_PTR)apiSetMap + entry->NameOffset), entry->NameLength / sizeof(wchar_t));
|
||||
printf("-----------\n[%05d]: Contract Name: %ls\n", i, name.data());
|
||||
|
||||
for (ULONG x = 0; x < entry->ValueCount; x++)
|
||||
{
|
||||
auto value =
|
||||
(PAPI_SET_VALUE_ENTRY)((ULONG_PTR)apiSetMap + entry->ValueOffset + x * sizeof(API_SET_VALUE_ENTRY));
|
||||
// printf(" Value %d\n", x);
|
||||
// printf(" Flags: %08X\n", value->Flags);
|
||||
// printf(" NameOffset: %08X\n", value->NameOffset);
|
||||
// printf(" NameLength: %08X\n", value->NameLength);
|
||||
// printf(" ValueOffset: %08X\n", value->ValueOffset);
|
||||
// printf(" ValueLength: %08X\n", value->ValueLength);
|
||||
|
||||
std::wstring hostName((wchar_t*)((ULONG_PTR)apiSetMap + value->NameOffset),
|
||||
value->NameLength / sizeof(wchar_t));
|
||||
std::wstring altName((wchar_t*)((ULONG_PTR)apiSetMap + value->ValueOffset),
|
||||
value->ValueLength / sizeof(wchar_t));
|
||||
printf(" HostName: %ls - AltName: %ls\n", hostName.empty() ? L"<none>" : hostName.data(),
|
||||
altName.empty() ? L"<none>" : altName.data());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Internal
|
||||
void create_header_file(const std::vector<uint8_t>& data)
|
||||
{
|
||||
FILE* output;
|
||||
fopen_s(&output, "api-set.h", "w");
|
||||
if (!output)
|
||||
{
|
||||
printf("Failed to create output file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(output, "#pragma once\n\n");
|
||||
fprintf(output, "#include <stdint.h>\n\n");
|
||||
fprintf(output, "const uint8_t api_set_blob[] = {\n");
|
||||
for (ULONG i = 0; i < data.size(); i++)
|
||||
{
|
||||
fprintf(output, "0x%02X, ", data[i]);
|
||||
if (i % 16 == 15)
|
||||
{
|
||||
fprintf(output, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(output, "};\n");
|
||||
fclose(output);
|
||||
}
|
||||
Reference in New Issue
Block a user