我一直在思考如何保护我的C/ c++代码不被反汇编和逆向工程破坏。通常情况下,在我的代码中,我绝不会宽恕这种行为;然而,为了各种人的安全,我目前正在研究的协议决不能被检查或理解。
现在这对我来说是一个新的主题,互联网并没有真正的资源来防止逆向工程,而是描述了大量关于如何逆向工程的信息
到目前为止我想到的一些事情是:
Code injection (calling dummy functions before and after actual function calls)
Code obfustication (mangles the disassembly of the binary)
Write my own startup routines (harder for debuggers to bind to)
void startup();
int _start()
{
startup( );
exit (0)
}
void startup()
{
/* code here */
}
Runtime check for debuggers (and force exit if detected)
Function trampolines
void trampoline(void (*fnptr)(), bool ping = false)
{
if(ping)
fnptr();
else
trampoline(fnptr, true);
}
Pointless allocations and deallocations (stack changes a lot)
Pointless dummy calls and trampolines (tons of jumping in disassembly output)
Tons of casting (for obfuscated disassembly)
我的意思是,这些是我想过的一些事情,但它们都可以在适当的时间框架内由代码分析师解决。我还有别的选择吗?
我不认为任何代码都是牢不可破的,但奖励必须非常棒,才能让人们愿意尝试它。
话虽如此,你还是应该做以下事情:
Use the highest optimization level possible (reverse engineering is not only about getting the assembly sequence, it is also about understanding the code and porting it into a higher-level language such as C). Highly optimized code can be a b---h to follow.
Make structures dense by not having larger data types than necessary. Rearrange structure members between official code releases. Rearranged bit fields in structures are also something you can use.
You can check for the presence of certain values which shouldn't be changed (a copyright message is an example). If a byte vector contains "vwxyz" you can have another byte vector containing "abcde" and compare the differences. The function doing it should not be passed pointers to the vectors but use external pointers defined in other modules as (pseudo-C code) "char *p1=&string1[539];" and "char p2=&string2[-11731];". That way there won't be any pointers pointing exactly at the two strings. In the comparison code you then compare for "(p1-539+i)-*(p2+11731+i)==some value". The cracker will think it is safe to change string1 because no one appears to reference it. Bury the test in some unexpected place.
尝试自己破解汇编代码,看看哪些是容易的,哪些是困难的。您可以尝试一些想法,使代码更难进行反向工程,并使调试更加困难。