最近研究 FLUENT ADDON 有一些进展,先是读出了 addon.bin 的编码规则,再进一步的话可以利用反汇编来还原出 SOFC 的源文件。
为什么是 SOFC,因为它提供了 object 文件,比较容易入手。
之前因为 rpvar 在并行版中会出现一些问题,而从 sofc.h 可以看到有对 rpvar 的修正,就从这相关的函数开始吧。
步骤其实还比较简单:
1 dumpbin 得到 fc.obj 的汇编代码,以 pull_real_from_cache 函数为例:
汇编代码:
_pull_real_from_cache: 00001D50: 55 push ebp 00001D51: 8B EC mov ebp,esp 00001D53: 51 push ecx 00001D54: 8B 45 08 mov eax,dword ptr [ebp+8] 00001D57: 3B 05 00 00 00 00 cmp eax,dword ptr [?old_rpvar@?1??pull_real_from_cache@@9@9] 00001D5D: 75 08 jne 00001D67 00001D5F: D9 05 00 00 00 00 fld dword ptr [?old_result@?1??pull_real_from_cache@@9@9] 00001D65: EB 6C jmp 00001DD3 00001D67: 8B 4D 08 mov ecx,dword ptr [ebp+8] 00001D6A: 89 0D 00 00 00 00 mov dword ptr [?old_rpvar@?1??pull_real_from_cache@@9@9],ecx 00001D70: C7 05 00 00 00 00 mov dword ptr [?old_result@?1??pull_real_from_cache@@9@9],0 00 00 00 00 00001D7A: C7 45 FC 00 00 00 mov dword ptr [ebp-4],0 00 00001D81: EB 09 jmp 00001D8C 00001D83: 8B 55 FC mov edx,dword ptr [ebp-4] 00001D86: 83 C2 01 add edx,1 00001D89: 89 55 FC mov dword ptr [ebp-4],edx 00001D8C: 8B 45 FC mov eax,dword ptr [ebp-4] 00001D8F: 3B 05 00 00 00 00 cmp eax,dword ptr [_rvars_count] 00001D95: 7D 36 jge 00001DCD 00001D97: 8B 4D 08 mov ecx,dword ptr [ebp+8] 00001D9A: 51 push ecx 00001D9B: 8B 55 FC mov edx,dword ptr [ebp-4] 00001D9E: 8B 04 95 00 00 00 mov eax,dword ptr _rvars[edx*4] 00 00001DA5: 50 push eax 00001DA6: E8 00 00 00 00 call _strcmp 00001DAB: 83 C4 08 add esp,8 00001DAE: 85 C0 test eax,eax 00001DB0: 75 19 jne 00001DCB 00001DB2: 8B 4D FC mov ecx,dword ptr [ebp-4] 00001DB5: 8B 15 00 00 00 00 mov edx,dword ptr [_rvars_vals] 00001DBB: 8B 04 8A mov eax,dword ptr [edx+ecx*4] 00001DBE: A3 00 00 00 00 mov dword ptr [?old_result@?1??pull_real_from_cache@@9@9],eax 00001DC3: D9 05 00 00 00 00 fld dword ptr [?old_result@?1??pull_real_from_cache@@9@9] 00001DC9: EB 08 jmp 00001DD3 00001DCB: EB B6 jmp 00001D83 00001DCD: D9 05 00 00 00 00 fld dword ptr [__real@cb189680] 00001DD3: 8B E5 mov esp,ebp 00001DD5: 5D pop ebp 00001DD6: C3 ret 00001DD7: CC int 3 00001DD8: CC int 3 00001DD9: CC int 3 00001DDA: CC int 3 00001DDB: CC int 3 00001DDC: CC int 3 00001DDD: CC int 3 00001DDE: CC int 3 00001DDF: CC int 3
2 写出对应的 C 代码
#include <stdio.h> extern char *rvars[]; extern float * rvars_vals; extern int rvars_count; float pull_real_from_cache(char *rpvar) { static char * old_rpvar; static float old_result; int i = 0; if (rpvar == old_rpvar) { return old_result; } old_rpvar = rpvar; old_result = 0.0; for (i=0; i<rvars_count; ++i) { if (strcmp(rpvar, rvars[i]) == 0) { old_result = rvars_vals[i]; return old_result; } } return 0.0f; }
4 完成,继续下一个
ps: 需要注意一点,dumpbin 的版本太低(比如VC6自带的dumpbin)的话反汇编的代码有些问题,尽量使用高版本的dumpbin