如何通过反汇编技术修改某dll的默认读取路径

文章讲述了通过ida反汇编dll文件,定位到读取文件路径的代码,发现目录名由qword_1805F9E10指针决定。通过替换该指针并调整函数参数顺序,实现从原路径到自定义目录(ice)的文件读取。修改过程涉及对x64汇编的理解,包括寄存器参数传递。文章最后表达了对完全解析机器码意义的探索兴趣。
摘要由CSDN通过智能技术生成

最近接到一个需求,需要修改某个dll的功能,使得其可以读取到客户指定的目录下的文件,而不是dll原来的路径

通过ida定位到了读取文件的路径是通过sprintf来组装的,使用ida反汇编得出机器码如下:

.text:00000001800042AD 4C 8B 05 5C 5B 5F 00          mov     r8, cs:qword_1805F9E10
.text:00000001800042B4 8B F5                         mov     esi, ebp
.text:00000001800042B6 48 69 F6 08 EA 2B 00          imul    rsi, 2BEA08h
.text:00000001800042BD 48 8D 15 4C C6 0F 00          lea     rdx, aSSIni                     ; "%s\\%s.ini"
.text:00000001800042C4 48 8D 8C 24 30 01 00 00       lea     rcx, [rsp+918h+Source]          ; Buffer
.text:00000001800042CC 4C 8D 8C 3E 80 E8 23 00       lea     r9, [rsi+rdi+23E880h]
.text:00000001800042D4 E8 D7 9F 0B 00                call    sprintf

反汇编得出的C代码如下:


      sprintf(Source, "%s\\%s.ini", (const char *)qword_1805F9E10, (const char *)qword_1805F96D8 + v7 + 2353280);
     

我们的目标是将目录名替换,看上面代码可以得知,目录名为qword_1805f9e10这个指针,我们需要将其替换为其它名字,通过跳转可以查到%s\\%s.ini这个字符串在.rdata下:

.rdata:000000018010090E 00 00                         align 10h
.rdata:0000000180100910                               ; const char aSSIni[]
.rdata:0000000180100910 25 73 5C 25 73 2E 69 6E 69 00 aSSIni db '%s\%s.ini',0                 ; DATA XREF: sub_180004150+16D↑o
.rdata:000000018010091A 00 00                         align 4
.rdata:000000018010091C 00 00 7F 43                   dword_18010091C dd 437F0000h            ; DATA XREF: sub_180004150+F7↑r
.rdata:000000018010091C

可以看到这个25 73 5c 25 73 2e 69 63 69代表的就是%s\%s.ini的ascii码

刚好我们看到字符串后面还有4个字节的空间可以发挥

我们将其改为ice\%s.ini,ascii码为69 63 65 25 73 2e 69 63 69

修改的时候注意不能随意改变这些字符的长度,只能将不同的字节替换

如原来的是25 73 5C 25 73 2E 69 6E 69 00

修改后就是69 63 65 5C 25 73 2e 69 63 69

你可以缩短,将多余的都替换为00,如果后面有多余的0,且是预留的空间,则可以将原始字符串加长,就像上面两行一样,注意最后至少要留一个0,作为字符串的结尾,像我们这刚好还多出了字节,我多用了一个

从18010910-1801091a,都是我们随意操作的区域,总共10个字节

修改完这个字符串之后,还不能读取到ice目录下的配置,还需要修改sprintf的参数

从上面代码得知,原来是用%s\%s匹配两个参数,现在我们改成了ice\%s,就需要将原代码的最后一个参数调到前面

通过学习x64的汇编知识可以得知,一个函数传参的顺序是将数据传送到rcx rdx r8 r9这四个寄存器中

对照上面的代码也可以轻易知道哪个地址存的哪个参数,我们只需要修改数据存储的寄存器即可修改到传参的顺序

我们需要调整r8和r9的顺序,4C 8B 05 5C 5B 5F 00 就是传送字符串到r8寄存器的意思,其中,

4C 8B 是move数据到r8,后面05 5c 5B 5F 就是原目录的指针

4C 8D 8C 3E 80 E8 23 00则是move数据到r9,我们将这个4C 8D和上面一句的4C 8B,替换一下,

即第四个参数是r9,我们将它存到r8上,第三个参数咱存到r9上,由于我们将字符串改为了ice\%s.ini,接下来程序使用r8,而将r9给丢弃了,从而实现了目录的替换

经过上面的修改后,程序将会读取ice目录下的ini文件,而不是之前拼接的路径了

有人问了,如何修改?我的做法是通过vim -b xxx,再通过指令:%!xxd 得出二进制,再搜索对应的16进制数来修改,修改完成后,:%!xxd -r,再:wq保存,至于windows上怎么操作,那就不知道了...

以上内容均为自己摸索总结得出的,经过实操的,但机器码的解读还是有些不准确,

下一步是想完全解析出机器码所代表的含义,当我可以完全解析出机器码的含义后,将可以轻松改写程序的逻辑,哈哈哈哈

至于怎么解析机器码,我还没找到相应的资料...不知道大家有没有好的推荐??

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值