win32驱动开发中的内存偏移问题

       在反汇编一个windows下的usb设备驱动的过程中,我发现windows环境下的内存地址偏移计算结果与IDA计算结果的差异。最主要体现在偏移量的计算上,windows环境下的偏移是按照源地址类型来确定偏移量的。

    源代码:

.text:00010C78 ; ---------------------------------------------------------------------------
.text:00010C7B                 align 4
.text:00010C7C
.text:00010C7C ; =============== S U B R O U T I N E =======================================
.text:00010C7C
.text:00010C7C ; Attributes: bp-based frame
.text:00010C7C
.text:00010C7C sub_10C7C       proc near               ; CODE XREF: sub_10F08+100p
.text:00010C7C
.text:00010C7C DestinationString= UNICODE_STRING ptr -8
.text:00010C7C arg_0           = dword ptr  8
.text:00010C7C
.text:00010C7C                 push    ebp
.text:00010C7D                 mov     ebp, esp
.text:00010C7F                 push    ecx
.text:00010C80                 push    ecx
.text:00010C81                 push    ebx
.text:00010C82                 push    esi
.text:00010C83                 push    edi                  ;保存现场
.text:00010C84                 mov     edi, [ebp+arg_0] ;edi获取第一个参数
.text:00010C87                 mov     esi, [edi+28h] ;esi = *(edi+40)
.text:00010C8A                 lea     eax, [esi+74h] ;eax = *(esi+116)
.text:00010C8D                 push    eax             ; SourceString 保存源字符串的指针,调用规则,从左至右
.text:00010C8E                 lea     eax, [ebp+DestinationString]
.text:00010C91                 push    eax             ; DestinationString 保存目的字符串指针
.text:00010C92                 call    ds:RtlInitUnicodeString ;调用RtlInitUnicodeString 函数
.text:00010C98                 push    0               ; Enable ;参数0
.text:00010C9A                 lea     eax, [ebp+DestinationString] ;获取目的字符串
.text:00010C9D                 push    eax             ; SymbolicLinkName ;保存至堆栈
.text:00010C9E                 call    ds:IoSetDeviceInterfaceState ;调用IoSetDeviceInterfaceState
.text:00010CA4                 mov     ebx, ds:ExFreePool ;保存函数指针,以便下面call调用
.text:00010CAA                 mov     [ebp+arg_0], eax ;
.text:00010CAD                 mov     eax, [esi+10h]
.text:00010CB0                 test    eax, eax ;eax==0?
.text:00010CB2                 jz      short loc_10CB7
.text:00010CB4                 push    eax             ;
.text:00010CB5                 call    ebx ; ExFreePool
.text:00010CB7
.text:00010CB7 loc_10CB7:                              ; CODE XREF: sub_10C7C+36j
.text:00010CB7                 mov     esi, [esi+14h]
.text:00010CBA                 test    esi, esi
.text:00010CBC                 jz      short loc_10CC1
.text:00010CBE                 push    esi             ; P
.text:00010CBF                 call    ebx ; ExFreePool
.text:00010CC1
.text:00010CC1 loc_10CC1:                              ; CODE XREF: sub_10C7C+40j
.text:00010CC1                 push    edi
.text:00010CC2                 call    sub_1088A
.text:00010CC7                 mov     eax, [ebp+arg_0]
.text:00010CCA                 pop     edi
.text:00010CCB                 pop     esi
.text:00010CCC                 pop     ebx
.text:00010CCD                 leave
.text:00010CCE                 retn    4
.text:00010CCE sub_10C7C       endp

   如果以汇编的模式,这种偏移是对的,但是逆向回C语言格式的时候可就要注意了,因为Win32的地址偏移和源地址的类型有关。

   例如地址00010C87 处的代码:mov     esi, [edi+28h] ;意思就是esi = *(edi+40),根据上下文分析,传进来的参数是PDEVICE_OBJECT,那么你要是直接写成C语句:(ULONG*)(arg_0+40),这样就会导致错误,为啥?原因是地址偏移了sizeof(DEVICE_OBJECT)*40,就成了mov     esi, [edi+1cc0h]了。

   汇编语句下的偏移都是以char的长度计数的,因此,若把C语句改成(ULONG*)arg_0 + 10,或者(char*)arg_0+40,这样的语句在C语言下偏移正确了,+10的原因不用说了吧(ULONG = char*4)。

    总结经验:

mov     eax, [edi+60h]
sub     eax, 24h

此语句就是(char*)Irp->Tail.Overlay.CurrentStackLocation-24h,即为Irp->Tail.Overlay.CurrentStackLocation-1,进而表明此处使用了宏IoGetNextIrpStackLocation.

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值