反汇编PsConvertToGuiThread

还原的C代码在ReactOS的开源中已经给出了,这次只是想看看XP SP3下有什么不同。果然有一个发现,这个函数中有一部分代码在这个函数调用中是没有被执行。所以是hook的好位置。下面的汇编代码已经完全注释,还原成C就没有问题了。这次练习的主要目的是猜测其中局部变量的含义,通过注释此汇编代码,局部变量含义完全给出。凡是局部变量名前面都有一个‘l’作为Local的缩写,以便区分。大家可以通过这个函数动态获取两个SSDT表的入口。

nt!PsConvertToGuiThread:
805c3720 6a38            push    38h
805c3722 6810ac4d80      push    offset nt!ObWatchHandles+0x3c4 (804dac10)
805c3727 e8e457f7ff      call    nt!_SEH_prolog (80538f10)//检查相关句柄信息
805c372c 64a124010000    mov     eax,dword ptr fs:[00000124h]//KTHREAD.CurrentThread
805c3732 8bf0            mov     esi,eax//CurrentThread
805c3734 33db            xor     ebx,ebx
805c3736 389e40010000    cmp     byte ptr [esi+140h],bl//CurrentThread.PreviousMode==0?
805c373c 750a            jne     nt!PsConvertToGuiThread+0x28 (805c3748)//为0则跳转
805c373e b80d0000c0      mov     eax,0C000000Dh
805c3743 e91f010000      jmp     nt!PsConvertToGuiThread+0x147 (805c3867)//不为0则失败
805c3748 391d180b6780    cmp     dword ptr [nt!PspW32ProcessCallout (80670b18)],ebx//内核模式,*PspW32ProcessCallout==0?
805c374e 750a            jne     nt!PsConvertToGuiThread+0x3a (805c375a)
805c3750 b8220000c0      mov     eax,0C0000022h//失败
805c3755 e90d010000      jmp     nt!PsConvertToGuiThread+0x147 (805c3867)
805c375a 81bee0000000a03f5580 cmp dword ptr [esi+0E0h],offset nt!KeServiceDescriptorTable (80553fa0)//CurrentThread.ServiceTable==KeServiceDescriptorTable?
805c3764 740a            je      nt!PsConvertToGuiThread+0x50 (805c3770)
805c3766 b81b000040      mov     eax,4000001Bh//*PspW32ProcessCallout==NULL,失败
805c376b e9f7000000      jmp     nt!PsConvertToGuiThread+0x147 (805c3867)
805c3770 8b4644          mov     eax,dword ptr [esi+44h]//线程已经指向KeServiceDescriptorTable,那么KPROCESS CurrentThread.ApcState.Process
805c3773 8945e0          mov     dword ptr [ebp-20h],eax//lProcess=CurrentThread.ApcState.Process
805c3776 389e42010000    cmp     byte ptr [esi+142h],bl//CurrentThread.LargeStack==0?
805c377c 756a            jne     nt!PsConvertToGuiThread+0xc8 (805c37e8)
805c377e 33c0            xor     eax,eax
805c3780 8a86df000000    mov     al,byte ptr [esi+0DFh]//al=CurrentThread.InitialNode
805c3786 50              push    eax//CurrentThread.InitialNode
805c3787 6a01            push    1
805c3789 e820b8f4ff      call    nt!MmCreateKernelStack (8050efae)//创建内核堆栈
805c378e 8bf8            mov     edi,eax
805c3790 3bfb            cmp     edi,ebx//函数是否调用成功
805c3792 752a            jne     nt!PsConvertToGuiThread+0x9e (805c37be)
805c3794 895dfc          mov     dword ptr [ebp-4],ebx//tProcessHandle=0
805c3797 64a118000000    mov     eax,dword ptr fs:[00000018h]//&kPcr
805c379d 8945dc          mov     dword ptr [ebp-24h],eax//lkStartPcrAddress=&kPcr
805c37a0 c7403408000000  mov     dword ptr [eax+34h],8//lkStartPcrAddress->KdVersionBlock=8
805c37a7 eb07            jmp     nt!PsConvertToGuiThread+0x90 (805c37b0)
805c37a9 33c0            xor     eax,eax//这里永远不会被当前函数执行,hook的好位置
805c37ab 40              inc     eax
805c37ac c3              ret
805c37ad 8b65e8          mov     esp,dword ptr [ebp-18h]
805c37b0 834dfcff        or      dword ptr [ebp-4],0FFFFFFFFh//tProcessHandle=NtCurrentProcess()
805c37b4 b8170000c0      mov     eax,0C0000017h//失败
805c37b9 e9a9000000      jmp     nt!PsConvertToGuiThread+0x147 (805c3867)
805c37be b101            mov     cl,1//内核堆栈分配成功
805c37c0 ff15f4864d80    call    dword ptr [nt!_imp_KfRaiseIrql (804d86f4)]//提升IRQL权限
805c37c6 8845e7          mov     byte ptr [ebp-19h],al//lOldIrql=al
805c37c9 8d8700d0ffff    lea     eax,[edi-3000h]//-KERNEL_STACK_SIZE地址
805c37cf 50              push    eax
805c37d0 57              push    edi
805c37d1 e8bacff3ff      call    nt!KeSwitchKernelStack (80500790)//交换
805c37d6 8bf8            mov     edi,eax
805c37d8 8a4de7          mov     cl,byte ptr [ebp-19h]//cl=lOldIrql
805c37db ff151c874d80    call    dword ptr [nt!_imp_KfLowerIrql (804d871c)]//降低IRQL权限
805c37e1 53              push    ebx//0
805c37e2 57              push    edi//刚才MmCreateKernelStack函数返回的参数
805c37e3 e8ceb9f4ff      call    nt!MmDeleteKernelStack (8050f1b6)//释放资源
805c37e8 a10cbf5580      mov     eax,dword ptr [nt!PPerfGlobalGroupMask (8055bf0c)]//线程最大堆栈不为0
805c37ed 3bc3            cmp     eax,ebx//那么PPerfGlobalGroupMask[0]==0?
805c37ef 7447            je      nt!PsConvertToGuiThread+0x118 (805c3838)//为0则跳转
805c37f1 f6400401        test    byte ptr [eax+4],1//PPerfGlobalGroupMask[1]==1?
805c37f5 7441            je      nt!PsConvertToGuiThread+0x118 (805c3838)//为1也可以继续运行
805c37f7 8b86ec010000    mov     eax,dword ptr [esi+1ECh]//CurrentThread.Cid
805c37fd 8945d0          mov     dword ptr [ebp-30h],eax//lCid=CurrentThread.Cid
805c3800 8b86f0010000    mov     eax,dword ptr [esi+1F0h]//CurrentThread.Cid.UniqueThread
805c3806 8945d4          mov     dword ptr [ebp-2Ch],eax//lTID=CurrentThread.Cid.UniqueThread
805c3809 8b8668010000    mov     eax,dword ptr [esi+168h]//CurrentThread.StackBase
805c380f 8945b8          mov     dword ptr [ebp-48h],eax//lStackBase=CurrentThread.StackBase
805c3812 8b461c          mov     eax,dword ptr [esi+1Ch]//CurrentThread.StackLimit
805c3815 8945bc          mov     dword ptr [ebp-44h],eax//lStackLimit=CurrentThread.StackLimit
805c3818 895dc0          mov     dword ptr [ebp-40h],ebx
805c381b 895dc4          mov     dword ptr [ebp-3Ch],ebx
805c381e 895dc8          mov     dword ptr [ebp-38h],ebx
805c3821 895dcc          mov     dword ptr [ebp-34h],ebx//这里几个局部变量设置为0
805c3824 c645d8ff        mov     byte ptr [ebp-28h],0FFh//保留低8位
805c3828 6a24            push    24h
805c382a 8d45b8          lea     eax,[ebp-48h]
805c382d 50              push    eax//&lStackBase
805c382e 6823050000      push    523h
805c3833 e872ae0900      call    nt!PerfInfoLogBytes (8065e6aa)//这里调用这个函数检测相关错误
805c3838 6a01            push    1//PPerfGlobalGroupMask[0]=0或者PPerfGlobalGroupMask[1]==1时
805c383a ff75e0          push    dword ptr [ebp-20h]//lProcess
805c383d ff15180b6780    call    dword ptr [nt!PspW32ProcessCallout (80670b18)]//初始化lProcess的Win32Process结构
805c3843 3bc3            cmp     eax,ebx//判断函数调用是否成功
805c3845 7c20            jl      nt!PsConvertToGuiThread+0x147 (805c3867)//跳转失败
805c3847 c786e0000000603f5580 mov dword ptr [esi+0E0h],offset nt!KeServiceDescriptorTableShadow (80553f60)//存在视窗,则用KeServiceDescriptorTableShadow
805c3851 53              push    ebx//0
805c3852 56              push    esi//CurrentThread
805c3853 ff151c0b6780    call    dword ptr [nt!PspW32ThreadCallout (80670b1c)]//初始化线程中的Win32Thread字段
805c3859 3bc3            cmp     eax,ebx//判断函数调用是否成
805c385b 7d0a            jge     nt!PsConvertToGuiThread+0x147 (805c3867)//跳转成功
805c385d c786e0000000a03f5580 mov dword ptr [esi+0E0h],offset nt!KeServiceDescriptorTable (80553fa0)
805c3867 e8df56f7ff      call    nt!_SEH_epilog (80538f4b)
805c386c c3              ret
时间: 2024-10-12 13:09:10

反汇编PsConvertToGuiThread的相关文章

c++反汇编与逆向分析 小结

第一章  熟悉工作环境和相关工具1.1 熟悉OllyDBG  操作技巧1.2 反汇编静态分析工具 IDA(最专业的逆向工具)    快捷键    功能     Enter     跟进函数实现     Esc       返回跟进处    A         解释光标处的地址为一个字符串的首地址     B         十六进制数与二进制数转换    C         解释光标处的地址为一条指令     D         解释光标处的地址为数据,没按一次将会转换这个地址的数据长度   

通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的

实验一:通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的 学号:20135114 姓名:王朝宪 注: 原创作品转载请注明出处   <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 1 1)实验部分(以下命令为实验楼64位Linux虚拟机环境下适用,32位Linux环境可能会稍有不同) 使用 gcc –S –o main.s main.c -m32 命令编译成汇编代码,如下代码中的数字请自行修改以防与

Java 继承 反汇编 class A { } 执行结果

源代码: public class ExplorationJDKSource { /** * @param args */ public static void main(String[] args) { System.out.println(new A()); } } class A{} 结果截图: 源代码执行 javap -c ExplorationJDKSource.class命令 反汇编后的结果: 原因分析: 其实,在实例中,main方法实际上调用的是 public void print

浅析VS2010反汇编

第一篇 1. 如何进行反汇编 在调试的环境下,我们可以很方便地通过反汇编窗口查看程序生成的反汇编信息.如下图所示. 记得中断程序的运行,不然看不到反汇编的指令 看一个简单的程序及其生成的汇编指令 #include<stdio.h> #include<windows.h> const long Lenth=5060000/5; int main(){ while(true){ for(long i=0;i<Lenth;i++){ ; } Sleep(10); } } 汇编窗口

cpp反汇编之控制结构

控制结构主要是关于  if/else   switch/case 废话不多说..献上代码及反汇编分析.. #include<stdio.h> int main(int argc , char *argv[]) { int nInt = 9; // if(0 == nInt) __asm { cmp DWORD PTR [EBP - 4h] , 0 ; jle __exit; } // __asm { printf("%d\n" , nInt); /* push DWORD

apktool 反汇编apk包

apktool  可反汇编 apk包 1.java的环境要配好 2.首先下载 apktool.jar,apktool.bat ,aapt.exe .可进官网下载http://code.google.com/p/android-apktool/ 或者下载压缩包 3.命令行进入apktool.bat的文件目录 apktool d -f TESTNAME.apk dest_folder 反编译TESTNAME apk到文件夹dest_folder apktool b ABC 从文件夹ABC重建APK,

Linux环境下使用gcc编译,gdb反汇编C语言程序

使用虚拟机 VMware Workstation 10 Linux环境:Ubuntu 14.04 LTS Server amd64 我把过程截图如下. 首先是hello world程序: 备注: gcc -o 参数,指定生成程序文件名. gdb下,disas命令对应英文为disassembler,反汇编. 这里没有执行程序.如果想执行,会出现: [email protected]:~$./helloworld Hello World! [email protected]:~$ 当然,前面要加 .

反汇编工具使用

内核开发,kernel panic是再常见不过的了,根据异常栈通常即可定位出代码出错的大概位置,但是有些时候我们还是会需要使用反汇编工具来帮助我们定位一些异常,objdump. 该反汇编工具存在于prebuilts/gcc/linux-x86/arm/gcc-linaro-aarch64-linux-gnu/bin/文件夹下,可参考如下使用方法: 1)   prebuilts/gcc/linux-x86/arm/gcc-linaro-aarch64-linux-gnu/bin/aarch64-l

C/C++流程与反汇编

众所周知,任何程序都可以由三种基本控制结构组成,分别是循序结构,选择结构,循环结构. 这三种结构翻译成汇编语言又是怎样的呢?这里主要考虑的是debug版本.对于release版本经过各种优化后结果不一样,不作考虑.这里的编译器采用的是Visual Studio 2008 顺序结构没什么悬念,这里就不提了,首先看下选择结构. 选择结构,主要有两种表现方式:if{ }else if{ } else{ }与 switch{case : case : default:} 首先来看下 if判断分支 if