Il2cppHacker.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. import {il2cppApi} from "../il2cppApi";
  2. import {log, logHHex} from "../../logger";
  3. import {
  4. DUMP_SO_PATH,
  5. GetMethodInfoFromIndex_Addr, GetTypeInfoFromTypeIndex_Addr,
  6. IDA_SCRIPT_PATH, MEMORY_DUMP_SO_PATH,
  7. soName,
  8. stringLiteralPath
  9. } from "../../config";
  10. import {Action_dumpSo, Action_getGameObject, Action_getObject, Action_getStringLiteral} from "./Il2cppHackerAction";
  11. import {Il2cppString} from "./struct/Il2cppString";
  12. import {Il2CppGlobalMetadataHeader} from "../struct/Il2CppGlobalMetadataHeader";
  13. import {Il2cppMetadataRegistration} from "../struct/Il2cppMetadataRegistration";
  14. import {Il2cppHackerApi} from "./Il2cppHackerApi";
  15. import {Il2cppMetadataUsageObj} from "../struct/Il2cppMetadataUsageObj";
  16. import {Il2cppBridgeApi} from "./Il2cppBridgeApi";
  17. import {Tabledefs} from "../tabledefs";
  18. import {Il2CppClass} from "../struct/Il2CppClass";
  19. import {MethodInfo} from "../struct/MethodInfo";
  20. import {Il2CppType} from "../struct/Il2CppType";
  21. import {JsonCreate} from "../JsonCreate";
  22. import {Il2CppFieldInfo} from "../struct/Il2CppFieldInfo";
  23. let il2cpp_got = false;
  24. let INIT_SUCCESS = -2;
  25. let s_Il2CppMetadataRegistration_addr = 0x82e550;
  26. let s_GlobalMetadataHeader = 0x82e568;
  27. let s_Il2CppCodeRegistration_addr = 0x82e54c;
  28. // let s_Il2CppMetadataRegistration_addr = 0xA02CC0;
  29. // let s_GlobalMetadataHeader = 0XA02CF0;
  30. // let s_Il2CppCodeRegistration_addr =0XA02CB8;
  31. let il2cpp_path;
  32. let il2cppHandler;
  33. let dumpModule = null;
  34. let process;
  35. let once=false;
  36. export var Il2cppHacker = {
  37. getEncodeIndexType(index) {
  38. return ((index & 0xE0000000) >> 29);
  39. },
  40. createObject: function () {
  41. if (!il2cpp_got) {
  42. Il2cppHacker.waitInject(Action_getObject);
  43. return;
  44. }
  45. let addr = Module.findBaseAddress(soName);
  46. let stringLiteral_2053 = addr.add(0x73f240);
  47. logHHex(stringLiteral_2053);
  48. log("uint :" + stringLiteral_2053.readU32());
  49. // a01013
  50. let Il2CppMetadataUsage = this.getEncodeIndexType(stringLiteral_2053.readU32());
  51. log("Il2CppMetadataUsage:" + Il2CppMetadataUsage);
  52. },
  53. dumpIDAScript: function () {
  54. if (s_Il2CppMetadataRegistration_addr == null) {
  55. log("you must know the s_Il2CppMetadataRegistration addr");
  56. return;
  57. }
  58. if (!il2cpp_got) {
  59. this.waitInject(Action_getStringLiteral);
  60. return;
  61. }
  62. let addr = Module.findBaseAddress(soName);
  63. if (addr == null) {
  64. setTimeout(function () {
  65. Il2cppHacker.dumpIDAScript();
  66. }, 5000);//该延迟很关键
  67. return;
  68. }
  69. //直接调用SO
  70. // Il2cppBridgeApi.startInject(il2cppHandler);
  71. let nativePointer = addr.add(s_GlobalMetadataHeader).readPointer();
  72. let il2CppGlobalMetadataHeader = new Il2CppGlobalMetadataHeader(nativePointer);
  73. // log("addr:" + addr + " il2CppGlobalMetadataHeader:" + il2CppGlobalMetadataHeader);
  74. //
  75. // let nativePointer1 = addr.add(0x7df388);
  76. // logHHex(nativePointer1);
  77. // let number = il2CppGlobalMetadataHeader.version();
  78. // log("Il2cppVer:" + number);
  79. // // 可以使用该版本
  80. let metadata_reg = addr.add(s_Il2CppMetadataRegistration_addr).readPointer();
  81. let il2cppMetadataRegistration = new Il2cppMetadataRegistration(metadata_reg);
  82. let codeRegistration = addr.add(s_Il2CppCodeRegistration_addr).readPointer();
  83. this.metadataInit(il2CppGlobalMetadataHeader, il2cppMetadataRegistration, il2cppHandler, codeRegistration);
  84. },
  85. createIDAScript: function () {
  86. let stringLiteralCount = Il2cppBridgeApi.getStringLiteralCount();
  87. log("stringLiteralCount:" + stringLiteralCount);
  88. //输出ScriptString
  89. for (let i = 0; i < stringLiteralCount; i++) {
  90. let objFromIndex = Il2cppBridgeApi.getStringLiteralObjFromIndex(i);
  91. if (!objFromIndex.isNull()) {
  92. let stringLiteralString = objFromIndex.stringLiteral_string();
  93. let il2cppConstantOffset = objFromIndex.getIl2cppConstantOffset();
  94. JsonCreate.addStringLiteralToStringLiteralMap(il2cppConstantOffset, stringLiteralString);
  95. JsonCreate.addStringLiteralToScript(il2cppConstantOffset, stringLiteralString);
  96. }
  97. }
  98. //输出ScriptMetadata
  99. // let il2CppMetadataRegistrationTypeCount = Il2cppBridgeApi.getIl2CppMetadataRegistrationTypeCount();
  100. // log("il2CppMetadataRegistrationTypeCount:" + il2CppMetadataRegistrationTypeCount);
  101. // let count = 0;
  102. // for (let i = 0; i < il2CppMetadataRegistrationTypeCount; i++) {
  103. // let il2CppMetadataTypeInfoFromIndex = Il2cppBridgeApi.getIl2CppMetadataTypeInfoFromIndex(i);
  104. // if (!il2CppMetadataTypeInfoFromIndex.isNull()) {
  105. // count++;
  106. // let il2cppConstantOffset = il2CppMetadataTypeInfoFromIndex.getIl2cppConstantOffset();
  107. // let obj = il2CppMetadataTypeInfoFromIndex.obj();
  108. // let il2CppClass = new Il2CppClass(obj);
  109. // let namespaze = il2CppClass.namespaze();
  110. // let name = il2CppClass.getGenericName();
  111. // JsonCreate.addTypeInfoToScript(il2cppConstantOffset, namespaze, name);
  112. // }
  113. // }
  114. // log("typeInfo总数量:" + count);
  115. // let cppTypeCount = 0;
  116. // for (let i = 0; i < il2CppMetadataRegistrationTypeCount; i++) {
  117. // let il2CppTypeInfoFromIndex = Il2cppBridgeApi.getIl2CppTypeInfoFromIndex(i);
  118. // if (!il2CppTypeInfoFromIndex.isNull()) {
  119. // cppTypeCount++;
  120. // let offset = il2CppTypeInfoFromIndex.getIl2cppConstantOffset();
  121. // let obj1 = il2CppTypeInfoFromIndex.obj();
  122. // let il2CppType = new Il2CppType(obj1);
  123. // let klass = il2cppApi.il2cpp_class_from_type(il2CppType);
  124. // let namespaze1 = klass.namespaze();
  125. // let name1 = klass.name();
  126. // JsonCreate.addCppTypeToScript(offset, namespaze1, name1);
  127. // }
  128. // }
  129. // log("CppType总数量:" + cppTypeCount);
  130. //
  131. // let fieldRefsCount = Il2cppBridgeApi.getFieldRefsCount();
  132. // let fieldCount = 0;
  133. // for (let i = 0; i < fieldRefsCount; i++) {
  134. // let fieldInfoObjFromIndex = Il2cppBridgeApi.getFieldInfoObjFromIndex(i);
  135. // if (!fieldInfoObjFromIndex.isNull()) {
  136. // fieldCount++;
  137. // let offset = fieldInfoObjFromIndex.getIl2cppConstantOffset();
  138. // let obj2 = fieldInfoObjFromIndex.obj();
  139. // let il2CppFieldInfo = new Il2CppFieldInfo(obj2);
  140. // let filedName = il2CppFieldInfo.getFiledName();
  141. // let parent = il2CppFieldInfo.getParent();
  142. // JsonCreate.addFieldInfoToScript(offset, parent.name(), filedName);
  143. // }
  144. // }
  145. // log("fieldInfo总数量:" + fieldCount);
  146. //
  147. // //输出ScriptMethod
  148. // //泛型实现方法地址
  149. // let genericMethodCount = 0;
  150. // let il2cppGenericInstObjCount = Il2cppBridgeApi.getIl2cppGenericInstObjCount();
  151. // for (let i = 0; i < il2cppGenericInstObjCount; i++) {
  152. // let genericInstObjFromIndex = Il2cppBridgeApi.getIl2cppGenericInstObjFromIndex(i);
  153. // if (!genericInstObjFromIndex.isNull()) {
  154. // genericMethodCount++;
  155. // JsonCreate.addMethodInfoToScriptMethod(genericInstObjFromIndex.spaze(),
  156. // genericInstObjFromIndex.className(), genericInstObjFromIndex.methodName(), genericInstObjFromIndex.addr());
  157. // JsonCreate.addAddressToScriptAddress(genericInstObjFromIndex.addr());
  158. // }
  159. // }
  160. // log("泛型方法数量:" + genericMethodCount);
  161. // let methodTableCount = Il2cppBridgeApi.getMethodTableCount();
  162. // log("C# 方法数量:" + methodTableCount);
  163. // for (let i = 0; i < methodTableCount; i++) {
  164. // let il2cppMethodObjFromIndex = Il2cppBridgeApi.getIl2cppMethodObjFromIndex(i);
  165. // JsonCreate.addMethodInfoToScriptMethod(il2cppMethodObjFromIndex.spaze(), il2cppMethodObjFromIndex.className(),
  166. // il2cppMethodObjFromIndex.methodName(), il2cppMethodObjFromIndex.addr())
  167. // JsonCreate.addAddressToScriptAddress(il2cppMethodObjFromIndex.addr());
  168. // }
  169. // //输出常量表里的方法
  170. //
  171. // let metadataMethodTableCount = Il2cppBridgeApi.getMetadataMethodTableCount();
  172. // for (let i = 0; i < metadataMethodTableCount; i++) {
  173. // let metadataMethodObjFromIndex = Il2cppBridgeApi.getMetadataMethodObjFromIndex(i);
  174. // if (!metadataMethodObjFromIndex.isNull()) {
  175. // let obj3 = metadataMethodObjFromIndex.obj();
  176. // let methodInfo = new MethodInfo(obj3);
  177. // if (!methodInfo.isNull()) {
  178. // let constantOffset = metadataMethodObjFromIndex.getIl2cppConstantOffset();
  179. // let klass = methodInfo.getClass();
  180. // let class_name = klass.name();
  181. // //获取泛型
  182. // if (class_name.indexOf("`") !== -1) {
  183. // let split = class_name.split("`");
  184. // class_name = split[0];
  185. // class_name = class_name + klass.getGenericName();
  186. // }
  187. // JsonCreate.addMetadataMethodToScript(constantOffset, klass.namespaze(), class_name,
  188. // methodInfo.name(), methodInfo.getMethodPointerOffsetToInt());
  189. // }
  190. //
  191. // }
  192. //
  193. // }
  194. // log("常量表方法数量:" + metadataMethodTableCount);
  195. // // //输出到文件里
  196. // let stringLiteralFile = new File(stringLiteralPath, "wb");
  197. // stringLiteralFile.write(JsonCreate.parserStringLiteralToString());
  198. // stringLiteralFile.flush();
  199. // stringLiteralFile.close();
  200. // //
  201. // let IDAScriptPath = new File(IDA_SCRIPT_PATH, "wb");
  202. // IDAScriptPath.write(JsonCreate.parserScriptToString());
  203. // IDAScriptPath.flush();
  204. // IDAScriptPath.close();
  205. // log("out script success , path is " + IDA_SCRIPT_PATH);
  206. },
  207. metadataInit: function (il2CppGlobalMetadataHeader, il2cppMetadataRegistration, il2cppHandler, s_Il2CppCodeRegistration_addr) {
  208. let module = this.getDumpModule();
  209. // Il2cppBridgeApi.setGetTypeInfoFromTypeIndexAddr(GetTypeInfoFromTypeIndex_Addr);
  210. let medatadataInit = new NativeFunction(module.findExportByName("_ZN14MetadataParser4initEPvS0_S0_S0_"),
  211. "int", ['pointer', 'pointer', 'pointer', 'pointer']);
  212. medatadataInit(il2CppGlobalMetadataHeader, il2cppMetadataRegistration, il2cppHandler, s_Il2CppCodeRegistration_addr);
  213. // Il2cppHacker.createIDAScript();
  214. },
  215. getDumpModule: function () {
  216. if (dumpModule == null) {
  217. dumpModule = Module.load(DUMP_SO_PATH);
  218. }
  219. return dumpModule;
  220. },
  221. dumpSo: function () {
  222. log("il2cpp got:" + il2cpp_got);
  223. let addr = Module.findBaseAddress(soName);
  224. log("addr:" + addr);
  225. if (addr == null) {
  226. if (il2cpp_got) {
  227. setTimeout(function () {
  228. Il2cppHacker.dumpSo();
  229. },
  230. 1000);
  231. return;
  232. }
  233. Il2cppHacker.waitInject(Action_dumpSo);
  234. return;
  235. }
  236. if (once){
  237. return;
  238. }
  239. once=true;
  240. setTimeout(function (){
  241. let module = Process.findModuleByName(soName);
  242. log("module:"+module.base +" 64:"+module.base.readU64() +" size:"+module.size);
  243. let nativePointer = new NativePointer(module.base);
  244. console.log(hexdump(nativePointer, {
  245. offset: 0,
  246. length: 64,
  247. header: true,
  248. ansi: true
  249. }))
  250. // Il2cppBridgeApi.start64(module.base.readU64(),module.size);
  251. Memory.protect(ptr(module.base), module.size, 'rwx');
  252. let arrayBuffer = nativePointer.readByteArray(module.size);
  253. let file = new File(MEMORY_DUMP_SO_PATH, "wb");
  254. send("写入前")
  255. file.write(arrayBuffer);
  256. file.flush();
  257. file.close();
  258. log("lib地址:" + module.base + " size:" + module.size);
  259. log("dump so 结束")
  260. },10000);
  261. },
  262. getGameObject: function () {
  263. if (!il2cpp_got) {
  264. Il2cppHacker.waitInject(Action_getGameObject);
  265. return;
  266. }
  267. let addr = Module.findBaseAddress(soName);
  268. log("addr:" + addr);
  269. if (addr == null) {
  270. setTimeout(function () {
  271. Il2cppHacker.getGameObject();
  272. }, 1000);
  273. return;
  274. }
  275. log("start getGameObj :" + addr);
  276. var objMgr_on_start = new NativeFunction(addr.add(0x6D7AB4), 'void', ['pointer']);
  277. Interceptor.replace(addr.add(0x6D7AB4), new NativeCallback(function (self) {
  278. objMgr_on_start(self);
  279. log(" objMgr on start after call");
  280. //得到赋值
  281. let il2cppString = new Il2cppString(self.add(0x20).readPointer()); //读取指针的地址
  282. let cString = il2cppString.getCString();
  283. log("cString:" + cString);
  284. //获取il2cpp
  285. // Il2cppHackerApi.getMethodInfo("UnityEngine", "Object", "FindObjectOfType", 0);
  286. }, "void", ['pointer']));
  287. },
  288. waitInject: function (action) {
  289. let open = Module.findExportByName(null, "open");
  290. log("wait il2cpp");
  291. if (open != null) {
  292. Interceptor.attach(open, {
  293. onEnter: function (args) {
  294. let path = args[0].readCString();
  295. // log("path:" + path);
  296. if (path.indexOf(soName) !== -1) {
  297. this.hook = true;
  298. }
  299. },
  300. onLeave: function (retval) {
  301. // log("this.hook:" + this.hook);
  302. if (this.hook) {
  303. log("got il2cpp");
  304. il2cpp_got = true;
  305. // Interceptor.detachAll();
  306. Il2cppHacker.jumpAction(action)
  307. }
  308. },
  309. })
  310. }
  311. },
  312. jumpAction: function (action) {
  313. switch (action) {
  314. case Action_getGameObject:
  315. Il2cppHacker.getGameObject();
  316. break;
  317. case Action_getStringLiteral:
  318. Il2cppHacker.dumpIDAScript();
  319. break;
  320. case Action_getObject:
  321. Il2cppHacker.createObject();
  322. break
  323. case Action_dumpSo:
  324. Il2cppHacker.dumpSo();
  325. break
  326. }
  327. }
  328. }