Assist.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736
  1. // Assist.cpp : 定义 DLL 应用程序的导出函数。
  2. //
  3. #include "stdafx.h"
  4. #include "Assist.h"
  5. #include <stdio.h>
  6. #include <process.h>
  7. // 全局CallData;
  8. CALLDATA _cd_Go;
  9. CALLDATA _cd_Connect;
  10. CALLDATA _cd_Disconnect;
  11. CALLDATA _cd_CheckFW;
  12. CALLDATA _cd_CheckFW_CommunicationError;
  13. CALLDATA _cd_SaveAsOutputData;
  14. CALLDATA _cd_Go_SN;
  15. CALLDATA _cd_Go_CommunicationError;
  16. CALLDATA _cd_Go_SetCommunicationError;
  17. CALLDATA _cd_Initial_failed;
  18. CALLDATA _cd_ExternalException;
  19. // 调试耗时值ms;
  20. DWORD dwElapsed = 0;
  21. TCHAR g_szGoSN[32] = {0};
  22. DWORD dwCallAddr = 0;
  23. // 8组寄存器存储;
  24. DWORD dwEAX = 0;
  25. DWORD dwEBX = 0;
  26. DWORD dwECX = 0;
  27. DWORD dwEDX = 0;
  28. DWORD dwEBP = 0;
  29. DWORD dwESP = 0;
  30. DWORD dwESI = 0;
  31. DWORD dwEDI = 0;
  32. // 定义跳转函数;
  33. void Call_MyDisconnect();
  34. void Call_MyConnect();
  35. void Call_MyGo();
  36. void Call_MyGoSN();
  37. void Call_MyCheckFW();
  38. void Call_MyCheckFWCommunicationError();
  39. void Call_MySaveAsOutputData();
  40. void Call_MyInitial_Failed();
  41. void Call_MyGoCommunicationError();
  42. void Call_MyGoSetCommunicationError();
  43. void Call_MyExternalException();
  44. // 其他函数;
  45. void SetChannel(int nChannel);
  46. void SetSN(LPCTSTR lpSN);
  47. void ChangeSDK(int nSDK); // 0=410SDK, 1=310SDK;
  48. void InitCallData()
  49. {
  50. #pragma region 启动时Initial Communication:需要程序启动时注入;
  51. /*
  52. 此劫持需要在程序刚启动时注入,即在弹框出现前实现注入;
  53. 目前不实现程序时注入!
  54. */
  55. // 00401EB8 | E8 7BCB0C00 | call demo.4CEA38 | # 弹出Messagebox:Initial Communication Failed!
  56. _cd_Initial_failed.myCall = Call_MyInitial_Failed;
  57. // 00401EBD | FF4D CC | dec dword ptr ss:[ebp-34] |
  58. _cd_Initial_failed.dwBack2Addr = 0x00401EBD;
  59. // 00401EB8 | E8 7BCB0C00 | call demo.4CEA38 | # 弹出Messagebox:Initial Communication Failed!
  60. _cd_Initial_failed.dwOriginalAddr = 0x00401EB8;
  61. _cd_Initial_failed.dwOriginalCallAddr = 0x004CEA38;
  62. _cd_Initial_failed.nMyCallDataLen = JMP_DLEN;
  63. memset(_cd_Initial_failed.szMyCallData, 0x90, CALL_LEN);
  64. _cd_Initial_failed.szMyCallData[0] = 0xE9; // 汇编硬编码:jmp [4字节地址];
  65. *(LPDWORD)(&_cd_Initial_failed.szMyCallData[1]) = (DWORD)_cd_Initial_failed.myCall - _cd_Initial_failed.dwOriginalAddr - JMP_DLEN;
  66. #pragma endregion
  67. #pragma region Connect按钮劫持
  68. /*
  69. Connect存在External expection 异常弹框;
  70. 出现External弹框时,结束进程,统一由Call_MyExternalException处理;
  71. */
  72. //00415ECB | 0F84 6A040000 | je demo.41633B | # 关键跳:如果Connect失败实现跳转
  73. _cd_Connect.myCall = Call_MyConnect;
  74. // 00415ED1 | 6A 00 | push 0 |
  75. _cd_Connect.dwBack2Addr = 0x00415ED1;
  76. _cd_Connect.dwOriginalAddr = 0x00415ECB;
  77. _cd_Connect.dwOriginalCallAddr = 0x0041633B; // 此处是JMP,注意注入时不要调用为Call
  78. _cd_Connect.nMyCallDataLen = JMP_DLEN;
  79. memset(_cd_Connect.szMyCallData, 0x90, CALL_LEN);
  80. _cd_Connect.szMyCallData[0] = 0xE9; // 汇编硬编码:jmp [4字节地址];
  81. *(LPDWORD)(&_cd_Connect.szMyCallData[1]) = (DWORD)_cd_Connect.myCall - _cd_Connect.dwOriginalAddr - JMP_DLEN;
  82. #pragma endregion
  83. #pragma region Disconnect按钮劫持
  84. /*
  85. disconnect时,同样存在External expection 异常弹框;
  86. 出现External弹框时,结束进程,统一由Call_MyExternalException处理;
  87. */
  88. // 0043790B | E8 E4C90900 | call demo.4D42F4 | # 此处可能用于SetWindowText之类处理
  89. // 00437910 | FF4D F4 | dec dword ptr ss:[ebp-C] |
  90. _cd_Disconnect.myCall = Call_MyDisconnect;
  91. _cd_Disconnect.dwBack2Addr = 0x00437910;
  92. _cd_Disconnect.dwOriginalAddr = 0x0043790B;
  93. _cd_Disconnect.dwOriginalCallAddr = 0x004D42F4;
  94. _cd_Disconnect.nMyCallDataLen = JMP_DLEN;
  95. memset(_cd_Disconnect.szMyCallData, 0x90, CALL_LEN);
  96. _cd_Disconnect.szMyCallData[0] = 0xE9; // 汇编硬编码:jmp [4字节地址];
  97. *(LPDWORD)(&_cd_Disconnect.szMyCallData[1]) = (DWORD)_cd_Disconnect.myCall - _cd_Disconnect.dwOriginalAddr - JMP_DLEN;
  98. #pragma endregion
  99. #pragma region ExternalException
  100. // 必须获取模块地址:ca210ctrl.dll
  101. HMODULE hModule = GetModuleHandle(_T("Ca210Ctrl.dll"));
  102. // 044D677C | FF15 78645404 | call dword ptr ds:[<&RaiseException>] |
  103. _cd_ExternalException.myCall = Call_MyExternalException;
  104. // 044D6782 | 5F | pop edi |
  105. _cd_ExternalException.dwBack2Addr = (DWORD)hModule + 0x106782;
  106. _cd_ExternalException.dwOriginalAddr = (DWORD)hModule + 0x10677C;
  107. _cd_ExternalException.dwOriginalCallAddr = 0x769F05B0;
  108. _cd_ExternalException.nMyCallDataLen = JMP_DLEN;
  109. memset(_cd_ExternalException.szMyCallData, 0x90, CALL_LEN);
  110. _cd_ExternalException.szMyCallData[0] = 0xE9; // 汇编硬编码:jmp [4字节地址];
  111. *(LPDWORD)(&_cd_ExternalException.szMyCallData[1]) = (DWORD)_cd_ExternalException.myCall - _cd_ExternalException.dwOriginalAddr - JMP_DLEN;
  112. #pragma endregion
  113. #pragma region Go按钮劫持
  114. /* 成功执行后的处理 */
  115. _cd_Go.myCall = Call_MyGo;
  116. _cd_Go.dwBack2Addr = 0x004376B0;
  117. // 004376AB | E8 50A30C00 | call demo.501A00
  118. _cd_Go.dwOriginalAddr = 0x004376AB;
  119. _cd_Go.dwOriginalCallAddr = 0x00501A00;
  120. _cd_Go.nMyCallDataLen = JMP_DLEN;
  121. memset(_cd_Go.szMyCallData, 0x90, CALL_LEN);
  122. _cd_Go.szMyCallData[0] = 0xE9; // 汇编硬编码:jmp [4字节地址];
  123. *(LPDWORD)(&_cd_Go.szMyCallData[1]) = (DWORD)_cd_Go.myCall - _cd_Go.dwOriginalAddr - JMP_DLEN;
  124. // 获取SN字符串;
  125. // 00417AEC | E8 9BA5FEFF | call demo.40208C |
  126. // 00417AF1 | E8 722C0700 | call demo.48A768 |
  127. _cd_Go_SN.myCall = Call_MyGoSN;
  128. _cd_Go_SN.dwBack2Addr = 0x00417AF1;
  129. // 004376AB | E8 50A30C00 | call demo.501A00
  130. _cd_Go_SN.dwOriginalAddr = 0x00417AEC;
  131. _cd_Go_SN.dwOriginalCallAddr = 0x0040208C;
  132. _cd_Go_SN.nMyCallDataLen = JMP_DLEN;
  133. memset(_cd_Go_SN.szMyCallData, 0x90, CALL_LEN);
  134. _cd_Go_SN.szMyCallData[0] = 0xE9; // 汇编硬编码:jmp [4字节地址];
  135. *(LPDWORD)(&_cd_Go_SN.szMyCallData[1]) = (DWORD)_cd_Go_SN.myCall - _cd_Go_SN.dwOriginalAddr - JMP_DLEN;
  136. // 消除 Set Communication Error 弹框;
  137. // 00417FCD | E8 666A0B00 | call demo.4CEA38 |
  138. _cd_Go_SetCommunicationError.myCall = Call_MyGoSetCommunicationError;
  139. _cd_Go_SetCommunicationError.dwBack2Addr = 0x00417FD2;
  140. // 00417FD2 | FF8D F4E8FFFF| dec dword ptr ss:[ebp-170C]|
  141. _cd_Go_SetCommunicationError.dwOriginalAddr = 0x00417FCD;
  142. _cd_Go_SetCommunicationError.dwOriginalCallAddr = 0x004CEA38;
  143. _cd_Go_SetCommunicationError.nMyCallDataLen = JMP_DLEN;
  144. memset(_cd_Go_SetCommunicationError.szMyCallData, 0x90, CALL_LEN);
  145. _cd_Go_SetCommunicationError.szMyCallData[0] = 0xE9; // 汇编硬编码:jmp [4字节地址];
  146. *(LPDWORD)(&_cd_Go_SetCommunicationError.szMyCallData[1]) = (DWORD)_cd_Go_SetCommunicationError.myCall - _cd_Go_SetCommunicationError.dwOriginalAddr - JMP_DLEN;
  147. // 消除Communication Error弹框;
  148. // 00404408 | E8 2BA60C00| call demo.4CEA38|
  149. _cd_Go_CommunicationError.myCall = Call_MyGoCommunicationError;
  150. _cd_Go_CommunicationError.dwBack2Addr = 0x0040440D;
  151. // 0040440D | FF4D BC | dec dword ptr ss:[ebp-44] |
  152. _cd_Go_CommunicationError.dwOriginalAddr = 0x00404408;
  153. _cd_Go_CommunicationError.dwOriginalCallAddr = 0x004CEA38;
  154. _cd_Go_CommunicationError.nMyCallDataLen = JMP_DLEN;
  155. memset(_cd_Go_CommunicationError.szMyCallData, 0x90, CALL_LEN);
  156. _cd_Go_CommunicationError.szMyCallData[0] = 0xE9; // 汇编硬编码:jmp [4字节地址];
  157. *(LPDWORD)(&_cd_Go_CommunicationError.szMyCallData[1]) = (DWORD)_cd_Go_CommunicationError.myCall - _cd_Go_CommunicationError.dwOriginalAddr - JMP_DLEN;
  158. #pragma endregion
  159. #pragma region CheckFW按钮处理
  160. // 00404458 | E8 E7F70400 | call demo.453C44 | # 此处应该是执行I2CReadEx
  161. _cd_CheckFW.myCall = Call_MyCheckFW; // 成功获取版本后跳转处理;
  162. // 0040445D | 83C4 1C | add esp,1C |
  163. _cd_CheckFW.dwBack2Addr = 0x0040445D;
  164. _cd_CheckFW.dwOriginalAddr = 0x00404458;
  165. _cd_CheckFW.dwOriginalCallAddr = 0x453C44;
  166. _cd_CheckFW.nMyCallDataLen = JMP_DLEN;
  167. memset(_cd_CheckFW.szMyCallData, 0x90, CALL_LEN);
  168. _cd_CheckFW.szMyCallData[0] = 0xE9; // 汇编硬编码:jmp [4字节地址];
  169. *(LPDWORD)(&_cd_CheckFW.szMyCallData[1]) = (DWORD)_cd_CheckFW.myCall - _cd_CheckFW.dwOriginalAddr - JMP_DLEN;
  170. /* 针对弹框Communication Error的消除处理 */
  171. // 00404408 | E8 2BA60C00 | call demo.4CEA38 | # Dailogs::ShowMessage(string) 弹出提示框:Communication Error
  172. _cd_CheckFW_CommunicationError.myCall = Call_MyCheckFWCommunicationError; // 成功获取版本后跳转处理;
  173. // 0040440D | FF4D BC | dec dword ptr ss:[ebp-44] | [ebp-44]:&"脥I"
  174. _cd_CheckFW_CommunicationError.dwBack2Addr = 0x0040440D;
  175. _cd_CheckFW_CommunicationError.dwOriginalAddr = 0x00404408;
  176. _cd_CheckFW_CommunicationError.dwOriginalCallAddr = 0x4CEA38;
  177. _cd_CheckFW_CommunicationError.nMyCallDataLen = JMP_DLEN;
  178. memset(_cd_CheckFW_CommunicationError.szMyCallData, 0x90, CALL_LEN);
  179. _cd_CheckFW_CommunicationError.szMyCallData[0] = 0xE9; // 汇编硬编码:jmp [4字节地址];
  180. *(LPDWORD)(&_cd_CheckFW_CommunicationError.szMyCallData[1]) = (DWORD)_cd_CheckFW_CommunicationError.myCall - _cd_CheckFW_CommunicationError.dwOriginalAddr - JMP_DLEN;
  181. #pragma endregion
  182. }
  183. BOOL HijackedAllCall()
  184. {
  185. BOOL bHijack=FALSE;
  186. if ( !(bHijack = HijackedCall(&_cd_Connect)) )
  187. goto end;
  188. if ( !(bHijack = HijackedCall(&_cd_Disconnect)) )
  189. goto end;
  190. if ( !(bHijack = HijackedCall(&_cd_Go)) )
  191. goto end;
  192. if ( !(bHijack = HijackedCall(&_cd_Go_SN)) )
  193. goto end;
  194. if ( !(bHijack = HijackedCall(&_cd_Go_CommunicationError)) )
  195. goto end;
  196. if ( !(bHijack = HijackedCall(&_cd_Go_SetCommunicationError)) )
  197. goto end;
  198. if ( !(bHijack = HijackedCall(&_cd_ExternalException)) )
  199. goto end;
  200. if ( !(bHijack = HijackedCall(&_cd_CheckFW)) )
  201. goto end;
  202. if ( !(bHijack = HijackedCall(&_cd_CheckFW_CommunicationError)) )
  203. goto end;
  204. end:
  205. return bHijack;
  206. }
  207. // 劫持原始地址;
  208. BOOL HijackedCall2(CALLDATA *pCallData)
  209. {
  210. if ( !pCallData )
  211. return FALSE;
  212. memset(pCallData->szMyCallData, 0x90, CALL_LEN);
  213. pCallData->szMyCallData[0] = 0xE9; // 汇编硬编码:jmp [4字节地址];
  214. *(LPDWORD)(&pCallData->szMyCallData[1]) = (DWORD)pCallData->myCall - pCallData->dwOriginalAddr - 5;
  215. HANDLE hProc = GetCurrentProcess();
  216. // 将要劫持的地址指令备份下来;
  217. memset(pCallData->szOriginalAddrData, 0, CALL_LEN);
  218. if ( !ReadProcessMemory(hProc, (LPVOID)pCallData->dwOriginalAddr, pCallData->szOriginalAddrData, pCallData->nOriginalAddrDataLen, NULL) )
  219. {
  220. MessageBox(NULL, _T("读取内存失败"), _T("提示"),MB_OK);
  221. return FALSE;
  222. }
  223. // 将我们的Call地址指令写入目标地址;
  224. if ( !WriteProcessMemory(hProc, (LPVOID)pCallData->dwOriginalAddr, pCallData->szMyCallData, pCallData->nMyCallDataLen, NULL) )
  225. {
  226. MessageBox(NULL, _T("写入内存失败"), _T("提示"),MB_OK);
  227. return FALSE;
  228. }
  229. return TRUE;
  230. }
  231. BOOL HijackedCall(CALLDATA *pCallData)
  232. {
  233. if ( !pCallData )
  234. return FALSE;
  235. memset(pCallData->szMyCallData, 0, CALL_LEN);
  236. pCallData->szMyCallData[0] = 0xE9; // 汇编硬编码:jmp [4字节地址];
  237. *(LPDWORD)(&pCallData->szMyCallData[1]) = (DWORD)pCallData->myCall - pCallData->dwOriginalAddr - CALL_LEN;
  238. HANDLE hProc = GetCurrentProcess();
  239. // 将要劫持的地址指令备份下来;
  240. memset(pCallData->szOriginalAddrData, 0, CALL_LEN);
  241. if ( !ReadProcessMemory(hProc, (LPVOID)pCallData->dwOriginalAddr, pCallData->szOriginalAddrData, CALL_LEN, NULL) )
  242. {
  243. MessageBox(NULL, _T("读取内存失败"), _T("提示"),MB_OK);
  244. return FALSE;
  245. }
  246. // 将我们的Call地址指令写入目标地址;
  247. if ( !WriteProcessMemory(hProc, (LPVOID)pCallData->dwOriginalAddr, pCallData->szMyCallData, CALL_LEN, NULL) )
  248. {
  249. MessageBox(NULL, _T("写入内存失败"), _T("提示"),MB_OK);
  250. return FALSE;
  251. }
  252. return TRUE;
  253. }
  254. // 劫持原始地址;
  255. BOOL HijackedCall(LPVOID MyCall, LPVOID OriginalCall, BYTE (&szOriginalCallData)[CALL_LEN])
  256. {
  257. BYTE szMyCallData[CALL_LEN] = {0};
  258. szMyCallData[0] = 0xE9; // 汇编硬编码:jmp [4字节地址];
  259. *(LPDWORD)(&szMyCallData[1]) = (DWORD)MyCall - (DWORD)OriginalCall - CALL_LEN;
  260. HANDLE hProc = GetCurrentProcess();
  261. // 将要劫持的地址指令备份下来;
  262. if ( !ReadProcessMemory(hProc, OriginalCall, szOriginalCallData, CALL_LEN, NULL) )
  263. {
  264. MessageBox(NULL, _T("读取内存失败"), _T("提示"),MB_OK);
  265. return FALSE;
  266. }
  267. // 将我们的Call地址指令写入目标地址;
  268. if ( !WriteProcessMemory(hProc, OriginalCall, szMyCallData, CALL_LEN, NULL) )
  269. {
  270. MessageBox(NULL, _T("写入内存失败"), _T("提示"),MB_OK);
  271. return FALSE;
  272. }
  273. return TRUE;
  274. }
  275. BOOL RecoveryCall(CALLDATA *pCallData)
  276. {
  277. if ( !pCallData )
  278. return FALSE;
  279. // 将我们的Call地址指令写入目标地址;
  280. if ( !WriteProcessMemory(GetCurrentProcess(), (LPVOID)pCallData->dwOriginalAddr, pCallData->szOriginalAddrData, CALL_LEN, NULL) )
  281. {
  282. MessageBox(NULL, _T("写入内存失败"), _T("提示"),MB_OK);
  283. return FALSE;
  284. }
  285. return TRUE;
  286. }
  287. void MyInitialFailed()
  288. {
  289. MessageBox(NULL, _T("MyInitialFailed"), _T("MyInitialFailed"), MB_OK);
  290. }
  291. void __declspec(naked) Call_MyInitial_Failed()
  292. {
  293. __asm pushad;
  294. MyInitialFailed();
  295. __asm popad;
  296. // 不执行原call:原Call是Messagebox弹框,需要消除掉它;
  297. // __asm call _cd_Initial_failed.dwOriginalCallAddr;
  298. __asm jmp _cd_Initial_failed.dwBack2Addr;
  299. }
  300. void __declspec(naked) Call_MySaveAsOutputData()
  301. {
  302. //004AB3FC
  303. __asm {
  304. // 保存寄存器;
  305. mov dwEAX, EAX;
  306. mov dwEBX, EBX;
  307. mov dwECX, ECX;
  308. mov dwEDX, EDX;
  309. mov dwEBP, EBP;
  310. mov dwESP, ESP;
  311. mov dwESI, ESI;
  312. mov dwEDI, EDI;
  313. // my call
  314. mov eax,0x004AB3FC
  315. mov dl,1
  316. call dword ptr[eax]
  317. // 恢复寄存器;
  318. mov EAX, dwEAX;
  319. mov EBX, dwEBX;
  320. mov ECX, dwECX;
  321. mov EDX, dwEDX;
  322. mov EBP, dwEBP;
  323. mov ESP, dwESP;
  324. mov ESI, dwESI;
  325. mov EDI, dwEDI;
  326. // 返回
  327. ret
  328. }
  329. }
  330. void MyGo()
  331. {
  332. CHAR szMsg[MAX_PATH];
  333. DWORD dwElapsedAddr = 0x0052DF54;
  334. DWORD dwSNAddr = dwEBP - 0x5D0;
  335. sprintf_s(szMsg, "MyGo耗时:%ldms, SN:%08X, %s", *(LPDWORD)dwElapsedAddr, dwSNAddr, (CHAR*)(*(LPDWORD)dwSNAddr));
  336. MessageBoxA(NULL, szMsg, "MyGo", MB_OK);
  337. }
  338. void __declspec(naked) Call_MyGo()
  339. {
  340. // 备份寄存器;
  341. __asm{
  342. // 保存寄存器;
  343. mov dwEAX, EAX;
  344. mov dwEBX, EBX;
  345. mov dwECX, ECX;
  346. mov dwEDX, EDX;
  347. mov dwEBP, EBP;
  348. mov dwESP, ESP;
  349. mov dwESI, ESI;
  350. mov dwEDI, EDI;
  351. }
  352. MyGo();
  353. __asm{
  354. // 恢复寄存器;
  355. mov EAX, dwEAX;
  356. mov EBX, dwEBX;
  357. mov ECX, dwECX;
  358. mov EDX, dwEDX;
  359. mov EBP, dwEBP;
  360. mov ESP, dwESP;
  361. mov ESI, dwESI;
  362. mov EDI, dwEDI;
  363. // 执行原Call;
  364. call _cd_Go.dwOriginalCallAddr
  365. // 返回劫持地址下一行;
  366. jmp _cd_Go.dwBack2Addr
  367. }
  368. }
  369. void MyGoSN()
  370. {
  371. CHAR szMsg[MAX_PATH];
  372. DWORD dwSNAddr = dwEBP - 0x5D0;
  373. //_stprintf_s(szMsg, _T("MyGo %08X, %08X, %08X, %s"), dwEAX, dwSNAddr, DWORD(*(LPDWORD)dwSNAddr), (TCHAR*)(*(LPDWORD)dwSNAddr));
  374. sprintf_s(szMsg, "MyGo %08X, %08X, %08X, %s", dwEAX, dwSNAddr, DWORD(*(LPDWORD)dwSNAddr), (CHAR*)(*(LPDWORD)dwSNAddr));
  375. MessageBoxA(NULL, szMsg, "MyGoSN", MB_OK);
  376. }
  377. void __declspec(naked) Call_MyGoSN()
  378. {
  379. // 备份寄存器;
  380. __asm{
  381. // 保存寄存器;
  382. mov dwEAX, EAX;
  383. mov dwEBX, EBX;
  384. mov dwECX, ECX;
  385. mov dwEDX, EDX;
  386. mov dwEBP, EBP;
  387. mov dwESP, ESP;
  388. mov dwESI, ESI;
  389. mov dwEDI, EDI;
  390. }
  391. MyGoSN();
  392. __asm{
  393. // 恢复寄存器;
  394. mov EAX, dwEAX;
  395. mov EBX, dwEBX;
  396. mov ECX, dwECX;
  397. mov EDX, dwEDX;
  398. mov EBP, dwEBP;
  399. mov ESP, dwESP;
  400. mov ESI, dwESI;
  401. mov EDI, dwEDI;
  402. // 执行原Call;
  403. call _cd_Go_SN.dwOriginalCallAddr
  404. // 返回劫持地址下一行;
  405. jmp _cd_Go_SN.dwBack2Addr
  406. }
  407. }
  408. void MyGoSetCommunicationError()
  409. {
  410. MessageBox(NULL, _T("MyGoSetCommunicationError"), _T("劫持"), MB_OK);
  411. }
  412. void __declspec(naked) Call_MyGoSetCommunicationError()
  413. {
  414. // 备份寄存器;
  415. __asm{
  416. // 保存寄存器;
  417. mov dwEAX, EAX;
  418. mov dwEBX, EBX;
  419. mov dwECX, ECX;
  420. mov dwEDX, EDX;
  421. mov dwEBP, EBP;
  422. mov dwESP, ESP;
  423. mov dwESI, ESI;
  424. mov dwEDI, EDI;
  425. }
  426. MyGoSetCommunicationError();
  427. __asm{
  428. // 恢复寄存器;
  429. mov EAX, dwEAX;
  430. mov EBX, dwEBX;
  431. mov ECX, dwECX;
  432. mov EDX, dwEDX;
  433. mov EBP, dwEBP;
  434. mov ESP, dwESP;
  435. mov ESI, dwESI;
  436. mov EDI, dwEDI;
  437. // 执行原Call;
  438. //call _cd_Go_SetCommunicationError.dwOriginalCallAddr // 经验证,即使不执行原call,也会弹异常框;
  439. // 返回劫持地址下一行;
  440. jmp _cd_Go_SetCommunicationError.dwBack2Addr
  441. }
  442. }
  443. void MyGoCommunicationError()
  444. {
  445. MessageBox(NULL, _T("MyGoCommunicationError"), _T("劫持"), MB_OK);
  446. }
  447. void __declspec(naked) Call_MyGoCommunicationError()
  448. {
  449. // 备份寄存器;
  450. __asm{
  451. // 保存寄存器;
  452. mov dwEAX, EAX;
  453. mov dwEBX, EBX;
  454. mov dwECX, ECX;
  455. mov dwEDX, EDX;
  456. mov dwEBP, EBP;
  457. mov dwESP, ESP;
  458. mov dwESI, ESI;
  459. mov dwEDI, EDI;
  460. }
  461. MyGoCommunicationError();
  462. __asm{
  463. // 恢复寄存器;
  464. mov EAX, dwEAX;
  465. mov EBX, dwEBX;
  466. mov ECX, dwECX;
  467. mov EDX, dwEDX;
  468. mov EBP, dwEBP;
  469. mov ESP, dwESP;
  470. mov ESI, dwESI;
  471. mov EDI, dwEDI;
  472. // 执行原Call;
  473. //call _cd_Go_CommunicationError.dwOriginalCallAddr
  474. // 返回劫持地址下一行;
  475. jmp _cd_Go_CommunicationError.dwBack2Addr
  476. }
  477. }
  478. BOOL MyConnect()
  479. {
  480. // 读取AL的值; 0表示Connect失败;1表示成功;
  481. BYTE AL = LOBYTE(LOWORD(dwEAX));
  482. if ( AL == 0 )
  483. {
  484. MessageBox(NULL, _T("连接失败"), _T("连接提示"), MB_OK);
  485. return FALSE;
  486. }
  487. else
  488. {
  489. MessageBox(NULL, _T("连接成功"), _T("连接提示"), MB_OK);
  490. }
  491. return TRUE;
  492. }
  493. void __declspec(naked) Call_MyConnect()
  494. {
  495. // 备份寄存器;
  496. __asm mov dwEAX, eax;
  497. __asm pushad;
  498. if ( MyConnect() )
  499. {
  500. __asm{
  501. // 恢复寄存器;
  502. popad;
  503. // 成功:则继续正常的流程;
  504. jmp _cd_Connect.dwBack2Addr;
  505. }
  506. }
  507. else
  508. {
  509. __asm{
  510. // 恢复寄存器;
  511. popad;
  512. // 失败:JMP到出错处理;
  513. jmp _cd_Connect.dwOriginalCallAddr;
  514. }
  515. }
  516. }
  517. void MyExternalException()
  518. {
  519. MessageBox(NULL, _T("MyExternalExceptionE06D7363,重启异常待重启"), _T("提示"), MB_OK);
  520. ::exit(0);
  521. }
  522. void __declspec(naked) Call_MyExternalException()
  523. {
  524. // 备份寄存器;
  525. __asm {
  526. pushad;
  527. }
  528. MyExternalException();
  529. __asm
  530. {
  531. // 恢复寄存器;
  532. popad;
  533. // 失败:JMP到出错处理;
  534. call _cd_ExternalException.dwOriginalCallAddr;
  535. jmp _cd_ExternalException.dwBack2Addr;
  536. }
  537. }
  538. void MyDisconnect()
  539. {
  540. MessageBox(NULL, _T("MyDisconnect Function"), _T("MyDisconnect"), MB_OK);
  541. }
  542. void __declspec(naked) Call_MyDisconnect()
  543. {
  544. __asm pushad;
  545. MyDisconnect();
  546. __asm
  547. {
  548. popad;
  549. call _cd_Disconnect.dwOriginalCallAddr;
  550. jmp _cd_Disconnect.dwBack2Addr;
  551. }
  552. }
  553. void __declspec(naked) Call_MyCheckFW()
  554. {
  555. // 备份寄存器;
  556. __asm pushad;
  557. MessageBox(NULL, _T("Call_MyCheckFW"), _T("MyCheckFW"), MB_OK);
  558. __asm{
  559. // 恢复寄存器;
  560. popad;
  561. // 执行原call;
  562. call _cd_CheckFW.dwOriginalCallAddr;
  563. // 最后返回原Call地址下一行;
  564. jmp _cd_CheckFW.dwBack2Addr;
  565. }
  566. }
  567. void __declspec(naked) Call_MyCheckFWCommunicationError()
  568. {
  569. // 备份寄存器;
  570. __asm pushad;
  571. MessageBox(NULL, _T("Call_MyCheckFWCommunicationError"), _T("MyCheckFWCommunicationError"), MB_OK);
  572. __asm{
  573. // 恢复寄存器;
  574. popad;
  575. // 消除原call;
  576. // call _cd_CheckFW.dwOriginalCallAddr;
  577. // 最后返回原Call地址下一行;
  578. jmp _cd_CheckFW_CommunicationError.dwBack2Addr;
  579. }
  580. }
  581. void __declspec(naked) SetChannel()
  582. {
  583. // 备份寄存器;
  584. __asm{
  585. // 保存寄存器;
  586. mov dwEAX, EAX;
  587. mov dwEBX, EBX;
  588. mov dwECX, ECX;
  589. mov dwEDX, EDX;
  590. mov dwEBP, EBP;
  591. mov dwESP, ESP;
  592. mov dwESI, ESI;
  593. mov dwEDI, EDI;
  594. }
  595. MessageBox(NULL, _T("MyGo Function"), _T("MyGo"), MB_OK);
  596. __asm{
  597. // 恢复寄存器;
  598. mov EAX, dwEAX;
  599. mov EBX, dwEBX;
  600. mov ECX, dwECX;
  601. mov EDX, dwEDX;
  602. mov EBP, dwEBP;
  603. mov ESP, dwESP;
  604. mov ESI, dwESI;
  605. mov EDI, dwEDI;
  606. // 最后返回原Call地址下一行;
  607. jmp _cd_Go.dwBack2Addr;
  608. }
  609. }
  610. void SetSN(LPCTSTR lpSN)
  611. {
  612. }
  613. void ChangeSDK(int nSDK) // 0=410SDK, 1=310SDK;
  614. {
  615. }
  616. void __declspec(naked) Call_Connect()
  617. {
  618. //dwCallAddr = 0x004D5864;//0x004378B0;
  619. /*dwCallAddr = 0x004378B0;
  620. __asm {
  621. pushad;
  622. mov eax,0x02393F78;
  623. mov ebx,0x024856CC;
  624. mov ecx,0x004AB16C;
  625. mov edx,0x024156CC;
  626. call dwCallAddr;
  627. popad;
  628. }*/
  629. dwCallAddr = 0x00415DFC;
  630. __asm call dwCallAddr;
  631. }