当前位置: 首页 > 科技观察

网络安全编程:wcslen函数

时间:2023-03-19 17:12:09 科技观察

C语言逆向中的wslen函数是用来获取字符串长度的函数,准确的说是用来获取UNICODE字符串长度的函数。它的定义如下:size_twcslen(constwchar_t*string);此定义取自MSDN。wcslen()函数的具体用法这里就不介绍了,主要看它的反汇编代码实现。用OD打开一个自己写的程序。本程序使用了UNICODE字符串,同样使用了wsclen()函数来计算UNICODE字符串的长度函数。然后在OD中的wsclen()函数处设置断点并运行程序。当程序调用wcslen()函数时,OD会被中断。分别查看OD的反汇编窗口、转储窗口(也叫数据窗口)和堆栈窗口,如图1、图2、图3所示。图1反汇编窗口图2转储窗口图3堆栈窗口从图可以看出3、wcslen()函数的参数是UNICODE字符串“c:\windows\system32\notepad.exe”。图2显示了wcslen()函数参数的内存情况。图1是wcslen()函数的反汇编代码。wcslen()函数的反汇编代码如下:77C17FCCm>8BFFmovedi,edi77C17FCE55pushebp77C17FCF8BECmovebp,esp77C17FD18B4508moveax,dwordptr[ebp+8]77C17FD466:8B08movcx,wordptr[eax]77C17FD740inceax77C17FD840inceax77C17FD966:85C9testcx,cx77C17FDC^75F6jnzshort77C17FD477C17FDE2B4508subeax,dwordptr[ebp+8]77C17FE1D1F8sareax,177C17FE348deceax77C17FE45Dpopebp77C17FE5C3retn在在OD中,使用F8步进到77C17FD4的地址,查看寄存器eax的值。eax的值保存为wcslen()函数的参数。其实通过“moveax,dwordptr[ebp+8]”可以看出,eax被赋值为wcslen()函数的参数值。77C17FD466:8B08movcx,wordptr[eax]77C17FD740inceax77C17FD840inceax以上3段反汇编代码是将eax地址处的2字节内容赋值给cx寄存器,然后将eax地址连续加1两次。77C17FD966:85C9testcx,cx77C17FDC^75F47Cnz27short上面这句反汇编代码是为了测试cx中的内容是否为0。UNICODE字符串以两个0结尾。如果不是结尾,说明还没有到达UNICODE字符串的结尾,则跳转到77C17FD4的地址,再次执行“movcx,wordptr[eax]”指令。这个循环一个一个遍历UNICODE字符串,直到字符串结束。77C17FDE2B4508subeax,dwordptr[ebp+8]77C17FE1D1F8sareax,177C17FE348deceax上面循环遍历整个UNICODE字符串时,eax的值指向字符串末尾两个0之后的地址。因为从77C17FD4到77C17FD8这三个地址的代码可以看出,这个函数是先取字符串中的内容,然后修改UNICODE指针的地址。这样,得到字符串的结束地址后,再修改字符串指针的地址,指针就会指向字符串末尾两个0之后的地址。在77C17FDE处,将字符串的起始地址减去eax的地址(即字符串末尾两个0之后的地址),得到该字符串占用的内存字节数。在计算机中,二进制位左移一位相当于乘以2;右移一位相当于除以2。在77C17FEl中,sar指令是对目的操作数进行右移操作。“sareax,1”是将eax中的值除以2,结果保存在eax中。字符串以UNICODE存储,一个字符占2个字节。然后将占用的内存除以2,得到字符串的字符个数。“deceax”的作用是将eax的值减一,结果保存在eax中。最后,实现一个wcslen()函数。为了让它看起来像反汇编代码,写得复杂一点,如下:){wchar_t*wpChar=(wchar_t*)wText;wchar_twChar;intiNum=0;do{wChar=*wpChar;wpChar+=1;}while(wChar!=0);iNum=(BYTE*)wpChar-(BYTE*)wText;iNum/=2;iNum--;returniNum;}intmain(){wchar_t*wText=_TEXT("helloworld");printf("%d\r\n",wcslen(wText));printf("%d\r\n",MyWcslen(wText));return0;}

猜你喜欢