0x1初识OD下的中文字符
1.首先,我还是写一个简单的C语言输出中文字符串的程序。
2.然后我用OD打开这个程序,然后智能搜索中文字符串,看到“小菜鸟一枚”的字符串,回车进去,来到了013D1010int main()
{
char str1[100] = "小菜鸟一枚";
printf("中文字符串:%sn",str1);
system("pause");
return 1;
}
3. 013D1010这一行右键,数据窗口中跟随,看到:013D1010 |. A1 F4203D01 mov eax,dword ptr ds:[0x13D20F4] ; 小菜鸟一枚
013D1015 |. 8B0D F8203D01 mov ecx,dword ptr ds:[0x13D20F8] ; 鸟一枚
013D101B |. 66:8B15 FC203>mov dx,word ptr ds:[0x13D20FC] ; 枚
4.鼠标选中D0,发现“小”字只选中了一半,选中D0 A1,发现整个”小“字都被选中了,说明一个汉字在OD中是以两个16进制数据展示的,联想一下昨天的学习,是不是在vs 2010编译的时候,汉字也是占两个数值呢?013D20F4 D0 A1 B2 CB C4 F1 D2 BB C3 B6 小菜鸟一枚..中文
0x2中文字符的表现形式
1.思考一下,在前面我-48,-95表示小字,转化为16进制是FFFFFFD0 , FFFFFFA1 ,我又产生了一个疑问,难道FFFFFFD0 = D0?
输出结果:printf("%d %dn",0xD0,0xA1);
printf("%d %dn",0xFFFFFFD0,0xFFFFFFA1);
208 161
-48 -95
2.可以看到,两个数明明不相等,为什么输出D0,A1也能出现“小”字???
输出结果:printf("%c%cn",208,161);
printf("%c%cn",-48,-95);
小
小
3.那我再来将两个数转化为16进制,看看他们又有什么区别?
208+48 = 256
161+95 = 256
两位16进制数最大能表示的范围是16*16=256。
一个byet能表示的范围是-128~127。
输出结果:printf("%c%cn",208+256,161+256);
printf("%c%cn",-48+256,-95+256);
小
小
4.看到这的朋友可能就会说什么原码、补码、反码,反正我是没学过,不懂那玩意。继续看上面的代码,我们可以发现一个数字如果不在-128~127之间,那么将它加或减n个256之后,得到的数值一定会在这个范围内。
输出结果:printf("%c%cn",600,601);
printf("%c%cn",-400,-401);
XY
po
5.查ASCII码表600-256*2=88==》X,601-256*2=89==》Y,-400+256*2=112==》p,-401+256*2=111==》o,说明我猜想是正确的,OD中显示的数字D1可以在vs2010由一个很大的数加减256得到的,一样能输出汉字。
0x3中文字符在OD中的隐藏方式
1.既然数字也能通过%C输出字符串,那我们试试这样编写代码!
输出结果:int tInt[20] = {0xD0,0xA1,0xB2,0xCB,0xC4,0xF1,0xD2,0xBB,0xC3,0xB6};
for(int i = 0;tInt[i];i++)
{
printf("%c",tInt[i]);
}
printf("n");
小菜鸟一枚
2.此时我们把这个程序丢进OD,搜索字符串,发现搜索不到小菜鸟一枚这个字符串,然后F4到最下面一个赋值语句,看数据窗口。
看到这些问号的时候,你能联想到它就是中文字符串“小菜鸟一枚”吗?000C1021 |. 894D AC mov [local.21],ecx
000C1024 |. C745 B0 A1000>mov [local.20],0xA1
000C102B |. C745 B4 B2000>mov [local.19],0xB2
000C1032 |. C745 B8 CB000>mov [local.18],0xCB
000C1039 |. C745 BC C4000>mov [local.17],0xC4
000C1040 |. C745 C0 F1000>mov [local.16],0xF1
000C1047 |. C745 C4 D2000>mov [local.15],0xD2
000C104E |. C745 C8 BB000>mov [local.14],0xBB
000C1055 |. C745 CC C3000>mov [local.13],0xC3
000C105C |. C745 D0 B6000>mov [local.12],0xB6
000C1063 |. 8945 D4 mov [local.11],eax
000C1066 |. 8945 D8 mov [local.10],eax
000C1069 |. 8945 DC mov [local.9],eax
000C106C |. 8945 E0 mov [local.8],eax
000C106F |. 8945 E4 mov [local.7],eax
000C1072 |. 8945 E8 mov [local.6],eax
000C1075 |. 8945 EC mov [local.5],eax
000C1078 |. 8945 F0 mov [local.4],eax
000C107B |. 8945 F4 mov [local.3],eax
000C107E |. 8945 F8 mov [local.2],eax
000C1081 |. 85C9 test ecx,ecx
数据窗口
0042F774 D0 00 00 00 A1 00 00 00 B2 00 00 00 CB 00 00 00 ?..?..?..?..
0042F784 C4 00 00 00 F1 00 00 00 D2 00 00 00 BB 00 00 00 ?..?..?..?..
0042F794 C3 00 00 00 B6 00 00 00 ?..?....
而且这还是原始的数据,如果我对他进行加减乘除运算呢?一个中文汉字我都可以变化为两个字母或数字。
0x4总结
1.中文字符加密能防止字符串被OD搜索到,增加破解难度。
2.任何数据都能转化为char类型处理,在-128~127的范围内运算。