查看: 142|回复: 2

[转载图文] 混淆IDA F5的一个小技巧-x64

[复制链接]
发表于 2020-6-11 00:15:44 | 显示全部楼层 |阅读模式
  本文没有归到反-反汇编系列中,因为主要是对抗IDA-F5,让函数的参数显示的很难看(没从网上看到过类似的思路,可能是我书读的比较少...分享一下心得)
  本文介绍x64架构下的一个技巧,之后可能会研究一下x86架构下的对抗
  不可否认的是,这些技巧都会在动态调试时露出真面目,但是配合反调试技巧,分析难度会加倍
失败尝试  代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main(int argc, char** argv) {
puts("nop me");
puts("nop me");
return 0;
}
//visual studio 2019 x64 release

  打开IDA,再熟悉不过的流程...

混淆IDA F5的一个小技巧-x64

混淆IDA F5的一个小技巧-x64
  因为是x64-fastcall,第一个参数被保存在了rcx中,既然rcx都是Str:"nop me",那么是否可以把第二次的lea rcx,Str直接nop掉呢?
  patch后汇编如图:

混淆IDA F5的一个小技巧-x64

混淆IDA F5的一个小技巧-x64
  F5后如图:

混淆IDA F5的一个小技巧-x64

混淆IDA F5的一个小技巧-x64
  可以看到第二个puts(v3),只静态分析就不会得知输出什么了
运行崩溃  在call puts("nop me")时的调试状况

混淆IDA F5的一个小技巧-x64

混淆IDA F5的一个小技巧-x64
  rcx就是"nop me"的地址
  再运行一下,rcx直接变成了0xFFFFFFFF

混淆IDA F5的一个小技巧-x64

混淆IDA F5的一个小技巧-x64
  这样,运行到下一个puts(v3)时,程序就会因为非法的内存读而崩溃
原因  其实问题的根源很简单,rcx在函数内部被改掉了
  跟进puts函数内部,前几条指令就已经破坏了原先的rcx

混淆IDA F5的一个小技巧-x64

混淆IDA F5的一个小技巧-x64
  最后一行test rcx,rcx 直接把它清零了...
  一些思考:
  这里应该是因为rcx默认用来放函数的第一个参数,调用子函数时会破坏原先的rcx也属正常
  但是,在父函数没有改变rcx时,是否就可以达到我们欺骗IDA的目的呢?
改进源码  示例程序源码:
#define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

const char* s1 = "%s";
char buf[16];

int func() {
//这里用返回类型为int,返回一个无用的0
//主要是void时汇编层面一开始没调对,这样更轻松一点
puts("nop me");
puts("nop me");
puts("nop me");
puts("nop me");
puts("nop me");
puts("nop me");
puts("nop me");
puts("nop me");
puts("nop me");
puts("nop me");
return 0;
}

int main(int argc, char** argv) {
scanf(s1, buf);
puts(buf);
func();
func();
func();
func();
func();
scanf(s1, buf);
puts(buf);
return 0;
}
//visual studio 2019 x64 release

  程序中func()函数内写了这么多是不想让函数编译后被"内联"
  func()调用这么多次也是出于这个原因
patch  main函数的逻辑如下:

混淆IDA F5的一个小技巧-x64

混淆IDA F5的一个小技巧-x64
  我们的目的是隐藏第二个scanf("%s",buf)的参数,最好让F5的结果变成scanf(v3)这样
第一步  我们把func()的最后两个puts("nop me")直接nop掉,如图

混淆IDA F5的一个小技巧-x64

混淆IDA F5的一个小技巧-x64
  这并不会破坏func()的堆栈之类,程序可以正确运行
第二步  main函数patch也不复杂,把第二个scanf的lea rcx,Format&lea rdx,buf都nop掉即可

混淆IDA F5的一个小技巧-x64

混淆IDA F5的一个小技巧-x64
  这样会改变程序流程,像刚才的失败一样,直接非法访问内存崩溃
第三步  我们在刚刚的func()函数中的一堆nop里做一些手脚,如下:

混淆IDA F5的一个小技巧-x64

混淆IDA F5的一个小技巧-x64
结果  F5后的结果如下,第二个scanf(v3)已经面目全非了,运行也不会报错
  的确是两个scanf的效果,只是第二次scanf把上一次的\n吃掉了,看起来不对劲
  实际上只要在第一个scanf后加上一个getchar()即可,放对位置也不会影响我们func()中藏的rcx&rdx

混淆IDA F5的一个小技巧-x64

混淆IDA F5的一个小技巧-x64
补充  复现可以直接拿源码编译,示例程序没有放在附件中...因为有时上传不成功比较尴尬
  大佬轻喷,欢迎交流和指出错误和改进


温馨提示:
1.如果您喜欢这篇帖子,请给作者点赞评分,点赞会增加帖子的热度,评分会给作者加学币。(评分不会扣掉您的积分,系统每天都会重置您的评分额度)。
2.回复帖子不仅是对作者的最好奖励,还可以获得学币奖励,请尊重作者的劳动成果,拒绝做伸手党!
3.发广告、灌水回复等违规行为一经发现直接禁言,如果本帖内容涉嫌违规,请点击论坛底部的举报反馈按钮,也可以在【投诉建议】板块发帖举报。
论坛交流群:672619046

0

主题

4

帖子

0

精华

中级会员

Rank: 8Rank: 8

学币
99
荣耀
0
rank
0
违规
0

    发表于 2020-6-19 10:10:42 | 显示全部楼层
    6666  大佬厉害
    学逆向论坛-免费的逆向学习论坛

    0

    主题

    56

    帖子

    0

    精华

    中级会员

    Rank: 8Rank: 8

    学币
    94
    荣耀
    0
    rank
    0
    违规
    0

      发表于 2020-7-1 03:19:51 | 显示全部楼层
      吃水不忘挖井人,我也去发帖分享好的资源。
      学逆向论坛-免费的逆向学习论坛
      微信公众号
      快速回复 返回顶部 返回列表