Skip to content

Instantly share code, notes, and snippets.

@robert-nix
Last active April 21, 2016 21:44
Show Gist options
  • Select an option

  • Save robert-nix/4164860 to your computer and use it in GitHub Desktop.

Select an option

Save robert-nix/4164860 to your computer and use it in GitHub Desktop.
SC2 ids dumper (23260, 24247 offset; 1.5+ only) + ASLR support
/* Dump type ids for Units and Abils. SC2.
*
* Keep it simple: cl dump.cpp Version.lib
* May need to enable LAA if 32 bit.
*/
#include <Windows.h>
#include <psapi.h>
#include <TlHelp32.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
static int sc2Version = 0;
static HANDLE sc2Handle = NULL;
static uint32_t cUnitIndex = 0;
static uint32_t stringNameOffset = 0;
void DumpIds(uint32_t catalogRecordList);
uint32_t ReadUInt(uint32_t address);
uint32_t GetModuleBase(DWORD, char *);
int main() {
DWORD procIds[2048];
DWORD numProcs = 0;
DWORD procId = 0;
EnumProcesses(procIds, 2048, &numProcs);
numProcs /= sizeof(DWORD);
char sc2FilePath[512];
for (int i = 0; i < numProcs; ++i) {
char buf[512];
sc2Handle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 0, procIds[i]);
GetModuleBaseName(sc2Handle, 0, buf, 512);
if (strcmp(buf, "SC2.exe")) {
CloseHandle(sc2Handle);
continue;
}
GetModuleFileNameEx(sc2Handle, 0, sc2FilePath, 512);
procId = procIds[i];
printf("Found: %d %s\n", procId, sc2FilePath);
// sc2Handle = procHandle;
break;
}
if (sc2Handle == NULL) {
printf("Error: SC2.exe not found\n");
ExitProcess(1);
}
uint32_t baseAddr = GetModuleBase(procId, "SC2.exe");
printf("Base: %x\n", baseAddr);
DWORD infoSize = GetFileVersionInfoSize(sc2FilePath, 0);
void *infoBuffer = malloc(infoSize);
GetFileVersionInfo(sc2FilePath, 0, infoSize, infoBuffer);
VS_FIXEDFILEINFO *sc2VersionInfo;
VerQueryValue(infoBuffer, "\\", (LPVOID*)&sc2VersionInfo, 0);
sc2Version = sc2VersionInfo->dwFileVersionLS & 0xffff;
printf("Version %d\n", sc2Version);
free(infoBuffer);
uint32_t gameCatalog = 0;
switch(sc2Version) {
case 23260:
gameCatalog = 0xF62BA0u;
cUnitIndex = 0x110u;
stringNameOffset = 0x64u;
break;
case 24247: // HotS beta 2.0.0.24247
gameCatalog = 0x10C9B28u;
cUnitIndex = 0x11cu;
stringNameOffset = 0x40u;
break;
default:
printf("Error: Need offset for current version.\n");
ExitProcess(1);
}
uint32_t gameCatalogTable = ReadUInt(baseAddr + gameCatalog);
printf("\n\n-- Begin dump --\n-- Catalog@0x%x --\n", gameCatalogTable);
uint32_t abilCatalogList = ReadUInt(gameCatalogTable + 0x1c);
uint32_t unitCatalogList = ReadUInt(gameCatalogTable + cUnitIndex);
printf("\n-- CAbil@0x%x --\n", abilCatalogList);
DumpIds(abilCatalogList);
printf("\n-- CUnit@0x%x --\n", unitCatalogList);
DumpIds(unitCatalogList);
printf("\n-- End dump --\n");
CloseHandle(sc2Handle);
return 0;
}
void DumpIds(uint32_t catalogRecordList) {
uint32_t numEntries = ReadUInt(catalogRecordList + 0x50);
uint32_t recordsList = ReadUInt(catalogRecordList + 0x5c);
if (recordsList == 0) {
printf("-- Error dumping table@%x: no list of catalog records found.\n", catalogRecordList);
return;
}
char name[256];
for (uint32_t i = 0; i < numEntries; ++i) {
memset(name, 0, 256);
uint32_t recordPtr = ReadUInt(recordsList + 4 * i);
if (recordPtr == 0) {
printf("-- No record at index %d\n", i);
continue;
}
uint32_t stringPtr = ReadUInt(ReadUInt(recordPtr + stringNameOffset) + 0x10) + 4;
uint32_t stringLength = ReadUInt(stringPtr);
uint32_t stringDataPtr;
if (ReadUInt(stringPtr + 4) & 4) {
stringDataPtr = ReadUInt(stringPtr + 8);
} else {
stringDataPtr = stringPtr + 8;
}
ReadProcessMemory(sc2Handle, (LPCVOID)stringDataPtr, &name,
stringLength, 0);
printf("(%d, %d, '%s'),\n", sc2Version, i, name);
}
}
uint32_t ReadUInt(uint32_t address) {
uint32_t result = 0;
ReadProcessMemory(sc2Handle, (LPCVOID)address, &result,
sizeof(uint32_t), 0);
return result;
}
uint32_t GetModuleBase(DWORD procId, char* modName)
{
HANDLE snapshot;
MODULEENTRY32 modInfo;
snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, procId);
modInfo.dwSize = sizeof(MODULEENTRY32);
if (Module32First(snapshot, &modInfo))
{
printf("mod %s\n", modInfo.szModule);
if (!strcmp(modInfo.szModule, modName))
{
CloseHandle(snapshot);
return (uint32_t)modInfo.modBaseAddr;
}
while (Module32Next(snapshot, &modInfo))
{
printf("mod %s\n", modInfo.szModule);
if (!strcmp(modInfo.szModule, modName))
{
CloseHandle(snapshot);
return (uint32_t)modInfo.modBaseAddr;
}
}
}
CloseHandle(snapshot);
return 0;
}
@crorella
Copy link

Hello,
How do you determine the values for gameCatalog , cUnitIndex and stringNameOffset ? I'm trying to do the same for Heroes of the Storm but I don't know how to get that memory address. Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment