Hello,
so yesterday I started messing around with Watch Dogs and its Disrupt engine. The main code is located in Disrupt_b64.dll, but it’s packed. To unpack, simply attach IDA to the process and dump the loader segments. The following information is based on my base address: 000007FB46240000
Lua base functions
Watch Dogs makes heavy use of lua, almost all things internally are scripted using it. The lua base functions can be found at 000007FB4906FEA0. You’ll find something along these lines:
.rdata:000007FB4906FEA0 baseFuncs dq offset aAssert ; DATA XREF: sub_7FB47A528C0+27o .rdata:000007FB4906FEA0 ; "assert" .rdata:000007FB4906FEA8 dq offset luaB_assert .rdata:000007FB4906FEB0 dq offset aCollectgarbage ; "collectgarbage" .rdata:000007FB4906FEB8 dq offset luaB_collectgarbage .rdata:000007FB4906FEC0 dq offset aDofile ; "dofile" .rdata:000007FB4906FEC8 dq offset luaB_dofile .rdata:000007FB4906FED0 dq offset aError_1 ; "error" .rdata:000007FB4906FED8 dq offset luaB_error .rdata:000007FB4906FEE0 dq offset aGcinfo ; "gcinfo" .rdata:000007FB4906FEE8 dq offset luaB_gcinfo
These are the core lua functions and it’s useful to name them and also have a look at how they work (source can be found here to help understanding them http://www.lua.org/source/5.1/lbaselib.c.html)
Lua scripting functions
The lua scripting functions start with GetBaseHealth at 000007FB48E7F300 and look like this:
.rdata:000007FB48E7F300 off_7FB48E7F300 dq offset aGetbasehealth .rdata:000007FB48E7F300 ; DATA XREF: .text:000007FB46632DE0o .rdata:000007FB48E7F300 ; .text:000007FB46638130o .rdata:000007FB48E7F300 ; start of lua scripting functions .rdata:000007FB48E7F308 dq offset lua_GetBaseHealth .rdata:000007FB48E7F310 dq offset aGetcurrentheal ; "GetCurrentHealth" .rdata:000007FB48E7F318 dq offset lua_GetCurrentHealth .rdata:000007FB48E7F320 dq offset aIsalive ; "IsAlive" .rdata:000007FB48E7F328 dq offset lua_IsAlive .rdata:000007FB48E7F330 dq offset aIsdead ; "IsDead" .rdata:000007FB48E7F338 dq offset lua_IsDead
Mapping the functions
This might be just plain data for you in IDA due to the dump, but my following IDC script should help you finding all offsets and assigning all function names:
auto base = 0xSTART; auto end = 0xEND; auto c = (end - base) / 8; auto i; auto adr; auto name; auto ref; auto lastWasString; for (i=0;i<c;i++) { adr = base + i*8; MakeQword(base + i*8); if (GetSegmentAttr(adr, SEGATTR_TYPE) != 3) { SetSegmentType(base + i*8, 3); } // Check if string Message("Checking %x", adr); ref = Qword(adr); Message(" -- ref: %x", ref); auto type; type = GetStringType(ref); Message(" -- stringType: %x", type); if (type == 0) { Message("--> IsString"); auto string; string = GetString(ref, -1, 0); Message(" -- %s", string); lastWasString = 1; name = string; } else { lastWasString = 0; } // If no string, try to make code at target location if (!lastWasString) { auto result; // If no code if (GetSegmentAttr(ref, SEGATTR_TYPE) != 2) { result = MakeCode(ref); Message("-- MakeCode: %x", result); } // Try making function result = MakeFunction(ref, BADADDR); Message("-- MakeFunction: %x", result); // Rename auto tempName = "lua_" + name; result = MakeName(ref, tempName); Message("-- MakeName: %x", result); } Message("\n"); }
Just edit start/end at the top to match it to your offsets and let it run. This may take quite a while and will also toggle some IDA reanalysis afterwards, because it creates code out of data segments. But as a result, you get some nice looking lua functions properly named.
Lua functions dump
For those of you interested, here are some functions dumped from memory with their address: http://lms-dev.com/files/lua_functions_dump.txt