GameGuard StringDecryption
GameGuard StringDecryption
h"
char szDir[MAX_PATH];
char szTargetFileName[MAX_PATH];
ofstream oFile;
//Some sample strings - encrypted
BYTE szEncrypted1[] = {0x01, 0x34, 0x01, 0x31, 0xAA, 0x61, 0x54, 0x81, 0xA2, 0x9
D, 0x90, 0x7E, 0x39, 0x7E, 0x4D, 0xD1, 0x26, 0x00};
BYTE szEncrypted2[] = {0x01, 0xA7, 0x5A, 0x55, 0x6F, 0x11, 0x05, 0x3C, 0x6C, 0x1
B, 0xCF, 0x93, 0x32, 0xB3, 0x93, 0x7D, 0x01, 0x1D, 0x40, 0x87, 0x0B, 0xB0, 0x00}
;
BYTE szEncrypted3[] = {0x01, 0x42, 0x2B, 0xB2, 0x09, 0x1E, 0xE4, 0xA5, 0x51, 0xD
3, 0x29, 0x26, 0x00};
char *GetDirectoryFile(char *szFilename)
{
static char szPath[MAX_PATH];
strcpy_s(szPath, szDir);
strcat_s(szPath, szFilename);
return szPath;
}
void PathToFileName(char *szPath)
{
string str = szPath;
string res = str.substr(str.find_last_of("\\") + 1);
sprintf_s(szTargetFileName, "%s", res.c_str());
}
void StartLogging()
{
GetModuleFileNameA(NULL, szDir, MAX_PATH);
for(int i = strlen(szDir); i > 0; i--)
{
if(szDir[i] == '\\')
{
szDir[i + 1] = 0;
break;
}
}
char *szFilePath = GetDirectoryFile("GG Decrypt.txt");
remove(szFilePath);
oFile.open(szFilePath, ios::app);
}
void add_log(const char *fmt, ...)
{
if(oFile.good())
{
if(!fmt)
return;
va_list va_alist;
char logbuf[256] = {0};
va_start (va_alist, fmt);
_vsnprintf(logbuf+strlen(logbuf), sizeof(logbuf) - strlen(logbuf), fmt,
va_alist);
va_end (va_alist);
int i;
for(i = 0; i < iLen - 5; i++)
{
dwKey++;
dwKey = dwKey+dwKey*2;
BYTE bDL = dwKey;
bDL += 0x65;
szString[i] = (bDL ^ (szString[i+4]));
}
//Overwrite the end with a string terminator (the key, no actual part of
the string)
//String size + 5
for(int j = 0; j < 5; j++)
szString[i+j] = '\0';
return (char*)szString;
}
bool DecryptStringsInFile(DWORD dwStartAddress, DWORD dwSize, char *szOut)
{
_DecodeResult res;
_DecodedInst decodedInstructions[MAX_INSTRUCTIONS];
unsigned int decodedInstructionsCount = 0;
_OffsetType offset = 0;
DWORD dwPEHeader = dwStartAddress;
DWORD dwRunBase = GetOptionalHeader(dwStartAddress)->ImageBase; //Origin
al Base (ImageBase)
DWORD dwCodeSize = GetOptionalHeader(dwStartAddress)->SizeOfCode;
DWORD dwCodeStart = 0x1000; //Should be 0x1000 for standard files
DWORD dwCodeStartFixed = dwCodeStart;
DWORD dwOffset = 0, dwPushAddress = 0;
printf("Allocated: 0x%X\n", dwPEHeader);
printf("dwCodeStart: 0x%X\n", dwPEHeader + dwCodeStart);
printf("dwCodeSize: 0x%X\n\n", dwCodeSize);
//Works for most GameGuard modules
//This crappy sigscan finds the decryption routine 1 and 2
DWORD dwDecrypt1 = FindPattern(dwPEHeader + dwCodeStart, dwCodeSize, (BY
TE*)"\x81\xEC\x00\x00\x00\x00\xA1\x00\x00\x00\x00\x33\xC4\x89\x84\x24\x00\x00\x0
0\x00\xF6\x05\x70\x06\x44\x00\x01\x56", "xx????x????xxxxx????xx????xx");
DWORD dwDecrypt2 = FindPattern(dwDecrypt1 + 30, dwCodeSize, (BYTE*)"\x81
\xEC\x00\x00\x00\x00\xA1\x00\x00\x00\x00\x33\xC4\x89\x84\x24\x00\x00\x00\x00\xF6
\x05\x70\x06\x44\x00\x01\x56", "xx????x????xxxxx????xx????xx");
dwDecrypt1 -= dwPEHeader; //1 is used alot, mostlikely no errors
dwDecrypt2 -= dwPEHeader; //2 isnt used often, mostlikely also often use
d with dynamic pushes [PUSH EDX] etc.
//Static offsets if my sigscan fails
//DWORD dwDecrypt1 = 0x11A0; //Offset of Func1
//DWORD dwDecrypt2 = 0x10C0; //Offset of Func2
printf("dwDecrypt1: 0x%X\n", dwDecrypt1);
printf("dwDecrypt2: 0x%X\n", dwDecrypt2);
int i = 0;
while(true)
{
{
bool bRes = false;
DWORD dwRead = NULL;
HANDLE hFile = CreateFileA(szIn, GENERIC_READ, FILE_SHARE_READ, NULL, OP
EN_EXISTING, 0, NULL);
if(hFile)
{
printf("Handle: %X\n", hFile);
DWORD dwSizeOfFile = GetFileSize(hFile, NULL);
if(dwSizeOfFile > 0)
{
//You can also use MapViewOfFile, but this method is fas
ter and works too
void *pImage = VirtualAlloc(NULL, dwSizeOfFile, MEM_COMM
IT|MEM_RESERVE, PAGE_READWRITE);
if(pImage)
{
bRes = ReadFile(hFile, pImage, dwSizeOfFile, &dw
Read, NULL);
printf("Reading File: %X\n", bRes);
printf("Read: %i\n\n", dwRead);
if(bRes)
return DecryptStringsInFile((DWORD)pImag
e, dwRead, szOut);
}
VirtualFree(pImage, dwSizeOfFile, MEM_RELEASE);
}
CloseHandle(hFile);
}
return false;
}
int _tmain(int argc, _TCHAR* argv[])
{
StartLogging();
//A small decryption test
/*printf("GameGuard String decryption:\n");
printf("Encrypted: %s\n", szEncrypted1);
char *szRet = DecryptXOR(szEncrypted1, strlen((char*)szEncrypted1) + 1);
printf("Decrypted: %s\n\n", szRet);*/
char szFixedFile[MAX_PATH], szFilename[] = "C:\\Program Files (x86)\\Gar
ena Plus\\Apps\\BlackShot\\BlackShot\\system\\GG Dumps\\GameMon.des.exe";
strcpy(szFixedFile, szFilename);
strcat(szFixedFile, ".decrypted");
if(!OpenFileForDecryption(szFilename, szFixedFile))
printf("An error occured!\nCannot open or read the file.\n\n");
system("PAUSE");
return 0;
}