最近在学习驱动的逆向哎呀遇到一个很无助的问题,我根据IDA读汇编代码去分析发现有一段代码觉得很不可思议。下面是IDA贴出来的代码。
sub_11570 proc near ;
.text:00011570 push ebp
.text:00011571 mov ebp, esp
.text:00011573 push esi
.text:00011574 mov eax, ds:KeServiceDescriptorTable
.text:00011579 mov ecx, [eax]
.text:0001157B mov edx, [ecx+454h]
.text:00011581 mov dword_13000, edx;这里应该是获取NtWriteVirtualMemory的SSDT中的地址
.text:00011587 mov eax, ds:KeServiceDescriptorTable
.text:0001158C mov ecx, [eax]
.text:0001158E mov edx, [ecx+2E8h]
.text:00011594 mov dword_13004, edx;这里是获NtReadVirtualMemory的SSDT中的地址
.text:0001159A mov eax, ds:KeServiceDescriptorTable
.text:0001159F mov ecx, [eax]
.text:000115A1 mov edx, [ecx+154h]
.text:000115A7 mov dword_13020, edx;这个是获取GetContextThread的SSDT中的地址
.text:000115AD push offset s_Keattachproce ; "KeAttachProcess"
.text:000115B2 call sub_11490
.text:000115B2
.text:000115B7 mov dword_13008, eax;
这里返回的EAX应该是KeAttachProcess的地址
;这里还有一样令我觉得无语的就是他那个CALL里面不是特征码定位的是调用函数获取函数源地址
;那么我不明白为什么可以获取到NtOpenThread的源地址啊。这个好像是未导出函数丫
.text:000115BC push offset s_Pscreatesyste ; "PsCreateSystemThread"
.text:000115C1 call sub_11490
.text:000115C1
.text:000115C6 mov dword_1300C, eax;下面如此类推
.text:000115CB push offset s_Ntopenprocess ; "NtOpenProcess"
.text:000115D0 call sub_11490
.text:000115D0
.text:000115D5 mov dword_13010, eax
.text:000115DA push offset s_Ntopenthread ; "NtOpenThread"
.text:000115DF call sub_11490
.text:000115DF
.text:000115E4 mov dword_13014, eax
.text:000115E9 push offset s_Obopenobjectb ; "ObOpenObjectByPointer"
.text:000115EE call sub_11490
.text:000115EE
.text:000115F3 mov dword_13018, eax
.text:000115F8 mov esi, dword_13008;到这里有个分叉了,把KeAttachProcess的源地址传到ESI
.text:000115F8
.text:000115FE
.text:000115FE loc_115FE: ; CODE XREF: sub_11570+92j
.text:000115FE inc esi;加一操作
.text:000115FF cmp byte ptr [esi], 0E8h;比较是不是0xE8就是汇编的CALL
.text:00011602 jnz short loc_115FE;如果不是就调回分支开头哪里循环
.text:00011602
.text:00011604 mov edx, [esi+1]
.text:00011607 lea eax, [edx+esi+5];这里的EAX应该就是KiAttachProcess的源地址了吧
.text:0001160B mov dword_13008, eax
.text:00011610 mov esi, dword_13010;这里开始让我不明白了
.text:00011610
.text:00011616
.text:00011616 loc_11616: ; CODE XREF: sub_11570+AAj
.text:00011616 ; sub_11570+BAj
.text:00011616 inc esi;他也是一个循环获取NtOpenProcess的CALL的地址
.text:00011617 cmp byte ptr [esi], 0E8h;对比是不是CALL
.text:0001161A jnz short loc_11616;不是的话就循环一直到是
.text:0001161A
.text:0001161C mov edx, [esi+1]
.text:0001161F lea ecx, [edx+esi+5];这里的ECX应该就是获取到的CALL的地址了吧
.text:00011623 mov eax, dword_13018;这里开始不懂了,为什么要获取ObOpenObjectByPointer的地址跟CALL的地址进行比较啊
.text:00011628 cmp ecx, eax
.text:0001162A jnz short loc_11616;还一直循环到是一样为止
这个是过DNF驱动保护的驱动。谁都知道TPHook的是ObOpenObjectByPointer那里。但是如果TP先加载了。他不是获取到了不是函数调用的ObOpenObjectByPointer了吗。那个CALL地址已经改变了。
求帮忙分析啊。我实在搞不懂了请好心人解释以下这个函数的意思就可以了。
.text:0001162A
.text:0001162C mov dword_13010, esi
.text:00011632 mov esi, dword_13014
.text:00011632
.text:00011638
.text:00011638 loc_11638: ; CODE XREF: sub_11570+CCj
.text:00011638 ; sub_11570+DCj
.text:00011638 inc esi
.text:00011639 cmp byte ptr [esi], 0E8h
.text:0001163C jnz short loc_11638
.text:0001163C
.text:0001163E mov edx, [esi+1]
.text:00011641 lea ecx, [edx+esi+5]
.text:00011645 mov eax, dword_13018
.text:0001164A cmp ecx, eax
.text:0001164C jnz short loc_11638
.text:0001164C
.text:0001164E mov dword_13014, esi
.text:00011654 pop esi
.text:00011655 pop ebp
.text:00011656 retn
.text:00011656
.text:00011656 sub_11570 endp
下面的代码跟上面的都差不多了。都是循环。就是不明白他为什么要ObOpenObjectByPointer进行比较
新手逆向请大牛多多体谅。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!