逆向-字符串

在C语言中,字符串其实就是一个特殊的数组,一个以零结尾的字符数组而已,所以对于定位字符串中的字符的话可以参考上一篇博客-数组。这篇博客主要用于记录字符串的一些操作函数,以便于在逆向识别的时候可以顺利的还原为函数。这里因为在release版下其字符串操作函数会内嵌汇编,也就是说并不是使用call来调用函数,所以我们需要来逆向识别一下。

所以下面我们讨论的都是release版下的情况,并且使用的编译器为vc6.0,为什么使用这款编译器呢,因为这款编译器编译出来的字符串操作函数是有无分支优化的,而对于高版本的vs来说,使用的就是我们平常的逻辑(循环处理函数),高版本比较好识别。虽然vc6.0版本比较老了,就算我们平常遇不到,但是对于无分支优化的手段还是很值得我们去学习的,体会一下汇编的艺术。

下面我们主要来看一下以下几个函数的实现

strlen
strcpy
memcpy
strcmp

先来看第一个strlen

int main(int argc, char* argv[])
{
    return strlen("Hello World!\n");
}

对应的汇编代码

.text:00401000                 push    edi
.text:00401001                 mov     edi, offset aHelloWorld ; "Hello World!\n"
.text:00401006                 or      ecx, 0FFFFFFFFh  //相当于ecx=-1,无符号下为最大的整数
.text:00401009                 xor     eax, eax //eax=0
.text:0040100B                 repne scasb  //字符串扫描函数,当ecx不为0或者和al比较不相等时继续
.text:0040100D                 not     ecx
.text:0040100F                 dec     ecx
.text:00401010                 pop     edi
.text:00401011                 mov     eax, ecx
.text:00401013                 retn

对于上面的汇编代码先简单的分析一下,可以发现其并未用到循环,但是从其字符串扫描函数来看,其相当于做了一个循环(处理器有优化),对于上面的字符串扫描函数,也就是说当遇到字符串的结尾字符0时便会退出,而在扫描过程中ecx也会随之一直减。说到这里其实大家心里应该就有个概念了,此时减去的ecx的个数应该就是字符串长度,但是此时ecx也包括了最后的结尾0,而字符串长度是不包含结尾0的,所以在最后一处又使用dec减一获取正确的字符串长度。

ecx = 0xFFFFFFFF - len - 1 (末尾0)
ecx = -2-len
len = -2-ecx
len = -2 + neg(ecx)
len = -
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值