[Proxy] Safer disassembly of the steam api

This commit is contained in:
momo5502 2017-02-21 20:54:57 +01:00
parent 06472685e2
commit f5d5e76ac1
2 changed files with 41 additions and 18 deletions

View File

@ -56,31 +56,55 @@ namespace Steam
size_t Interface::getMethodParamSize(void* method) size_t Interface::getMethodParamSize(void* method)
{ {
unsigned char* methodPtr = static_cast<unsigned char*>(method); if (::Utils::Memory::IsBadCodePtr(method)) return 0;
for (; !::Utils::Memory::IsBadReadPtr(methodPtr); ++methodPtr)
ud_t ud;
ud_init(&ud);
ud_set_mode(&ud, 32);
ud_set_pc(&ud, reinterpret_cast<uint64_t>(method));
ud_set_input_buffer(&ud, reinterpret_cast<uint8_t*>(method), INT32_MAX);
while (true)
{ {
if (methodPtr[0] == 0xC2 && methodPtr[2] == 0) // __stdcall return ud_disassemble(&ud);
if (ud_insn_mnemonic(&ud) == UD_Iret)
{ {
return (static_cast<size_t>(methodPtr[1])/* / sizeof(void*)*/); auto operand = ud_insn_opr(&ud, 0);
if (operand->type == UD_OP_IMM && operand->size == 16)
{
return static_cast<size_t>(operand->lval.uword);
}
break;
} }
} }
return 0; return 0;
} }
std::string Interface::getMethodName(unsigned char* methodPtr) std::string Interface::getMethodName(unsigned char* methodPtr)
{ {
for(;!::Utils::Memory::IsBadReadPtr(methodPtr); ++methodPtr) if (::Utils::Memory::IsBadCodePtr(methodPtr)) return "";
ud_t ud;
ud_init(&ud);
ud_set_mode(&ud, 32);
ud_set_pc(&ud, reinterpret_cast<uint64_t>(methodPtr));
ud_set_input_buffer(&ud, reinterpret_cast<uint8_t*>(methodPtr), INT32_MAX);
while (true)
{ {
if(methodPtr[0] == 0x68) // Push ud_disassemble(&ud);
if (ud_insn_mnemonic(&ud) == UD_Iret) break;
if (ud_insn_mnemonic(&ud) == UD_Ipush)
{ {
char* name = *reinterpret_cast<char**>(&methodPtr[1]); auto operand = ud_insn_opr(&ud, 0);
if(::Utils::Memory::IsBadReadPtr(name)) return name; if (operand->type == UD_OP_IMM && operand->size == 32)
{
char* operandPtr = reinterpret_cast<char*>(operand->lval.udword);
if (!::Utils::Memory::IsBadReadPtr(operandPtr)) return operandPtr;
} }
else if(methodPtr[0] == 0xC2 && methodPtr[2] == 0) // __stdcall return
{
break;
} }
} }
@ -167,7 +191,6 @@ namespace Steam
else if (expectedParams == 48) // Legacy, expects VAC blob else if (expectedParams == 48) // Legacy, expects VAC blob
{ {
char blob[8] = { 0 }; char blob[8] = { 0 };
Proxy::ClientUser.invoke<bool>("SpawnProcess", blob, 0, ourPath, cmdline.data(), 0, ourDirectory, gameID.bits, Proxy::AppId, mod.data(), 0, 0); Proxy::ClientUser.invoke<bool>("SpawnProcess", blob, 0, ourPath, cmdline.data(), 0, ourDirectory, gameID.bits, Proxy::AppId, mod.data(), 0, 0);
} }
else else

View File

@ -67,8 +67,8 @@ namespace Utils
bool Memory::IsBadReadPtr(const void* ptr) bool Memory::IsBadReadPtr(const void* ptr)
{ {
MEMORY_BASIC_INFORMATION mbi = { 0 }; MEMORY_BASIC_INFORMATION mbi = { nullptr };
if (::VirtualQuery(ptr, &mbi, sizeof(mbi))) if (VirtualQuery(ptr, &mbi, sizeof(mbi)))
{ {
DWORD mask = (PAGE_READONLY | PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY); DWORD mask = (PAGE_READONLY | PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY);
bool b = !(mbi.Protect & mask); bool b = !(mbi.Protect & mask);
@ -82,8 +82,8 @@ namespace Utils
bool Memory::IsBadCodePtr(const void* ptr) bool Memory::IsBadCodePtr(const void* ptr)
{ {
MEMORY_BASIC_INFORMATION mbi = { 0 }; MEMORY_BASIC_INFORMATION mbi = { nullptr };
if (::VirtualQuery(ptr, &mbi, sizeof(mbi))) if (VirtualQuery(ptr, &mbi, sizeof(mbi)))
{ {
DWORD mask = (PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY); DWORD mask = (PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY);
bool b = !(mbi.Protect & mask); bool b = !(mbi.Protect & mask);