• 1
预览模式: 普通 | 列表

内存映射文件

内存映射文件
  内存映射文件是由一个文件到一块内存的映射。Win32提供了允许应用程序把文件映射到一个进程的函数(CreateFileMapping)。这样,文件内的数据就可以用内存读/写指令来访问,而不是用ReadFile和WriteFile这样的I/O系统函数,从而提高了文件存取速度。
  这种函数最适用于需要读取文件并且对文件内包含的信息做语法分析的应用程序,如对输入文件进行语法分析的彩色语法编辑器,编译器等。把文件映射后进行读和分析,能让应用程序使用内存操作来操纵文件,而不必在文件里来回地读、写、移动文件指针。
  有些操作,如放弃“读”一个字符,在以前是相当复杂的,用户需要处理缓冲区的刷新问题。在引入了映射文件之后,就简单的多了。应用程序要做的只是使指针减少一个值。
  映射文件的另一个重要应用就是用来支持永久命名的共享内存。要在两个应用程序之间共享内存,可以在一个应用程序中创建一个文件并映射之,然后另一个应用程序可以通过打开和映射此文件把它作为共享的内存来使用。

查看更多...

分类:c/c++ | 固定链接 | 评论: 0 | 查看次数: 5871

VC++实现Win2000下直接读写磁盘扇区

  由于Windows 操作系统在很大程度上采取了访问安全保护机制(例如,在Windows操作系统下不能直接访问物理内存、不能使用各种DOS、BIOS中断等等),使得广大程序设计人员在长时间的开发过程中不知不觉地逐渐养成了这样的潜意识——在Windows操作系统下直接操纵硬件设备是极端困难和非常烦琐的,并将其看作Windows编程的一个禁区。尽管在大多数场合下这样的论断还算是贴切,但也并非对所有的硬件设备访问都那么困难。其实Windows在采取“实保护”措施的同时也提供了另外的一种有别于在DOS下访问硬件设备的方法,即把所有的硬件设备全部看做“文件”,并允许按照对文件的读写方式来对其进行数据存取访问。撰写本文的另外一个目的也就是帮助读者打消在Windows环境下对硬件编程的恐惧心理。

  对磁盘扇区数据的访问

  前面已经提过,在Windows 下把所有的设备当作文件进行操作。如果对串口进行编程或许不少读者还比较熟悉:对于串行端口1、2,可以用”COM1”、”COM2”作为参数调用CreateFile()函数,这里的”COM1”、”COM2”即以文件存放路径的方式指出了要操作的硬件设备。但是如果需要对磁盘的某个扇区进行读写,可能不少读者不会想到使用CreateFile()函数或是不知如何使用。其实,与对串行端口的访问类似,需要用与文件存放路径相类似的方式指出要操作的硬件设备(硬盘)。但是这里并不是用“DISK1”、“DISK2”等去标识某一块物理存在的硬盘。由于逻辑扇区是存在于逻辑分区上的,因此这里需要以某种特定的格式来指定需要访问的磁盘逻辑分区。对于逻辑分区X,其格式为”\\.\X:”。

查看更多...

分类:c/c++ | 固定链接 | 评论: 0 | 查看次数: 7013

虚拟内存与物理地址扩展(PAE)

 Windows的虚拟内存并非简单的指位于我们硬盘上的那个pagefile.sys文件,或者是在内存装不下的时候用于应急的“模拟内存”。事实上Windows的每一个进程都会同时用到物理内存和虚拟内存。


在Windows系统中,任何一个进程都会被赋予其自己的虚拟地址空间(虚拟内存),该虚拟地址空间可以覆盖了一个相当大的范围。对于一个32位进程,其可以拥有的地址空间为2^32=4GB,这使得一个指针可以使用从00000000h到FFFFFFFFh的4GB范围之内的任何一个值。虽然每一个32位进程可使用4GB的地址空间,但并不意味着每一个进程实际拥有4GB的物理地址空间,该地址空间仅仅是一个虚拟地址空间。此虚拟地址空间只是内存地址的一个范围,进程实际可以得到的物理内存要远小于其虚拟地址空间。进程的虚拟地址空间是为每个进程所私有的,在进程内运行的线程对内存空间的访问都被限制在调用进程之内,而不能访问属于其他进程的内存空间(比如声明这是A进程的4GB,那是B进程的4GB)。这样,在不同的进程中可以使用相同地址的指针来指向属于各自调用进程的内容而不会由此引起混乱。

查看更多...

分类:破解调试 | 固定链接 | 评论: 0 | 查看次数: 7091

读取物理内存

大家知道在windows NT中,如果已知虚拟地址可以通过进程页表或者内核提供的MmGetPhysicalAddress来取得对应的物理地址。现在我们反过来看一下,如果已知一个物理内存地 址 (假设地址有效),如何取得物理地址中的内容呢?经过一番思考后,我发现一个方法,但我这里先卖个关子,为什么呢?因为我觉得这个方法有些繁琐。经过和csdn的各位高手讨论之后,加上本人的一共总结出3种方法,现在想和大家分享一下,下面不再废话,立即进入正题 J[方法1]:使用内核提供的MmMapIoSpace函数原来内核早就提供了很简单的接口,就是MmMapIoSpace函数,不过在DDK文档中看到该函数的说明如下:PVOID MmMapIoSpace(    IN PHYSICAL_ADDRESS PhysicalAddress,    IN ULONG NumberOfBytes,IN MEMORY_CACHING_TYPE CacheType );它只有3个形参,这和实际Masm32v9.0声明的4个形参有所不同,为了确定,我通过 IDA 反汇编证实该函数确实有4个形参。经过测试,我猜测中间的ULONG NumberOfBytes参数实际由64位字节的(两个双字)高低两部分组成,即在Masm32v9.0中有:PVOID MmMapIoSpace(    IN PHYSICAL_ADDRESS PhysicalAddress,IN ULONG NumberOfBytesHighPart,IN ULONG NumberOfBytesLowPart,IN MEMORY_CACHING_TYPE CacheType );这样的话调用就很简单了:invoke   MmMapIoSpace,_phyaddr,0,4,MmNonCached若成功该函数返回影射后的虚拟地址,否则返回NULL。这样就可以间接达到读取物理地址中内容的第一个方法。但可能我对参数功能的猜测也有错误,如果有误请指出。不胜感谢。[方法2]:通过操作物理内存对象来完成到虚拟地址的影射简单的说这个方法的基本思想如下:a : 取得本进程句柄;b : 取得物理内存对象的句柄;c : 将物理内存地址影射到进程的虚拟地址空间中。下面是我从C改写后的汇编关键代码:;***************************************************************************GetValByPhyAddr   proc uses esi edi ebx _phyaddr      local   hpmem:dword      local   hp:dword      local   dwsize:dword      local   dwbase:dword      local   dwret:dword      local   cid:CLIENT_ID      local   stLR:LARGE_INTEGER      local   ObjAttrsMem:OBJECT_ATTRIBUTES      local   ObjAttrsP:OBJECT_ATTRIBUTES      mov    dwbase,0      mov    dwsize,4      push   _phyaddr      pop     stLR.LowPart      mov    stLR.HighPart,0      invoke PsGetCurrentProcessId      mov    cid.UniqueProcess,eax      mov    cid.UniqueThread,0      invoke InitObjAttrs,addr ObjAttrsP,0      ;取得本进程句柄      Invoke      ZwOpenProcess,addr hp,PROCESS_DUP_HANDLE,\                  addr ObjAttrsP,addr cid      invoke InitObjAttrs,addr ObjAttrsMem,addr devphymem      ;取得物理对象的句柄      Invoke     ZwOpenSection,addr hpmem,\                      SECTION_MAP_READ or SECTION_MAP_WRITE,\                      addr ObjAttrsMem      ;将物理内存地址影射到进程的虚拟地址空间中     invoke       ZwMapViewOfSection,hpmem,hp,addr dwbase,\                      0,4,addr stLR,addr dwsize,1,\                      MEM_TOP_DOWN,PAGE_READWRITEmov    edx,dwbase      mov    eax,[edx] ;取得影射后对应虚拟地址中的内容      mov    dwret,eax      ;释放资源      invoke ZwUnmapViewOfSection,hp,addr dwbase      invoke ZwClose,hpmem      invoke ZwClose,hp      mov    eax,dwret      retGetValByPhyAddr   endp;***************************************************************************[方法3]:关闭CPU分页机制达到直接读取物理地址的目的第3种方法就是我前面卖关子的方法 J ,这种方法不依赖于OS,了解保护模式的朋友都知道:进入保护模式后如果关闭分页机制则CPU就会将线形地址直接解释成物理地址。关闭分页很简单,只需3行汇编代码:mov     eax,cr0and     eax,7fffffffhmov     cr0,eax打开分页同样很简单:mov eax,cr0or eax,80000000h  mov cr0,eax既然这么简单,为什么我在前面说这个方法有些繁琐呢?原因之一是如果仅仅关闭分页就会使原来依赖于分页的windows变得一团糟,马上会发生著名的蓝屏现象,不爽哦!L那要怎么做呢?经过我的尝试,发现有3点非常重要:1 : 要保证windows处在较高的IRQL级别,防止关闭分页后        被打断;2 : 要将处理分页、读取物理地址的指令块放到线形地址等于        物理地址的页中;3 : 要做好数据的恢复工作。第1点和第3点都容易理解,可能有人会疑问第2点,为什么要放到线形地址等于物理地址的空间中呢?原因其实也很简单,就是一旦关闭分页,所有地址都将以物理地址来解释,如果先前的虚拟地址和物理地址不相同那么很可能就会发生执行错误指令流的问题。(当然也可以不相同,只要你能保证关分页后能执行正确指令即可。)那么如何将物理地址和虚拟地址设置为相同呢?我的方法是将虚拟地址对应地页表PTE中的物理页基址改为包容即可。我随机选择了一个虚拟地址 0x1c00000 ,为了简单它正好是页面的一个基址。下面我构造了它的PTE使得其中的物理也帧指向它:mov    edx,0ffdf0000h      mov    eax,[edx]      mov    tmp0,eax            ; 保存原始值      ;mov   dword ptr [edx],1c00027h      mov    dword ptr [edx],1c00007h      ;初始化PTE      mov    edx,0c03ff7c0h      mov    eax,[edx]      and     eax,0fffff000h      or eax,7h      mov    edx,0c030001ch      mov    ebx,[edx]      mov    tmp1,ebx                  ; 保存原始值      mov    dword ptr [edx],eax      ;刷新TLB      mov    eax,cr3      mov    cr3,eax            最后两句指令在我前一篇: <<Windows内核编程研究一:改变进程PTE>> 中有过说明,这里就不解释了。结束了PTE的设置后,下面就是将指令块拷贝到指定位置,代码如下:mov    ecx,slenmov    esi,subasmmov    edi,1c00000hcldrep            movsb而subasm指令块完成的就是实际设置分页和读取物理地址内容的工作,如下:subasm:            mov     eax,cr0            and     eax,7fffffffh                ;关闭分页机制            mov     cr0,eax                jmp     SHORT PageCPageC:            mov    edx,[ecx]mov    eax,cr0            or eax,80000000h             ;打开分页机制            mov    cr0,eax           jmp     SHORT PageOPageO:           jmp     edislen    =   $ - subasm借用一句话作为结尾“…一切都那么清楚明白,然而却无法透彻理解。理解就是改变,就是超越自己已有的认识。”

查看更多...

分类:破解调试 | 固定链接 | 评论: 0 | 查看次数: 6424

关于ring3到ring0的代码实现

☆ 利用调用门从Ring 3进入Ring 0

观察用户空间程序memdump.exe执行时CS、DS、FS所对应的段描述符:

--------------------------------------------------------------------------

查看更多...

分类:破解调试 | 固定链接 | 评论: 0 | 查看次数: 9223

GDT详解(全局描述符表)

在Protected Mode下,一个重要的必不可少的数据结构就是GDT(Global Descriptor Table)。 
为什么要有GDT?我们首先考虑一下在Real Mode下的编程模型: 
在Real Mode下,我们对一个内存地址的访问是通过Segment:Offset的方式来进行的,其中Segment是一个段的Base Address,一个Segment的最大长度是64 KB,这是16-bit系统所能表示的最大长度。而Offset则是相对于此Segment Base Address的偏移量。Base Address+Offset就是一个内存绝对地址。由此,我们可以看出,一个段具备两个因素:Base Address和Limit(段的最大长度),而对一个内存地址的访问,则是需要指出:使用哪个段?以及相对于这个段Base Address的Offset,这个Offset应该小于此段的Limit。当然对于16-bit系统,Limit不要指定,默认为最大长度64KB,而 16-bit的Offset也永远不可能大于此Limit。我们在实际编程的时候,使用16-bit段寄存器CS(Code Segment),DS(Data Segment),SS(Stack Segment)来指定Segment,CPU将段积存器中的数值向左偏移4-bit,放到20-bit的地址线上就成为20-bit的Base Address。 
到了Protected Mode,内存的管理模式分为两种,段模式和页模式,其中页模式也是基于段模式的。也就是说,Protected Mode的内存管理模式事实上是:纯段模式和段页式。进一步说,段模式是必不可少的,而页模式则是可选的——如果使用页模式,则是段页式;否则这是纯段模式。 
既然是这样,我们就先不去考虑页模式。对于段模式来讲,访问一个内存地址仍然使用Segment:Offset的方式,这是很自然的。由于 Protected Mode运行在32-bit系统上,那么Segment的两个因素:Base Address和Limit也都是32位的。IA-32允许将一个段的Base Address设为32-bit所能表示的任何值(Limit则可以被设为32-bit所能表示的,以2^12为倍数的任何指),而不象Real Mode下,一个段的Base Address只能是16的倍数(因为其低4-bit是通过左移运算得来的,只能为0,从而达到使用16-bit段寄存器表示20-bit Base Address的目的),而一个段的Limit只能为固定值64 KB。另外,Protected Mode,顾名思义,又为段模式提供了保护机制,也就说一个段的描述符需要规定对自身的访问权限(Access)。所以,在Protected Mode下,对一个段的描述则包括3方面因素:[Base Address, Limit, Access],它们加在一起被放在一个64-bit长的数据结构中,被称为段描述符。这种情况下,如果我们直接通过一个64-bit段描述符来引用一个段的时候,就必须使用一个64-bit长的段积存器装入这个段描述符。但Intel为了保持向后兼容,将段积存器仍然规定为16-bit(尽管每个段积存器事实上有一个64-bit长的不可见部分,但对于程序员来说,段积存器就是16-bit的),那么很明显,我们无法通过16-bit长度的段积存器来直接引用64-bit的段描述符。 

查看更多...

分类:内核探究 | 固定链接 | 评论: 0 | 查看次数: 7777

调试权限(debug权限)

介绍几个提升到debug权限的函数吧~!
GetCurrentProcessID            得到当前进程的ID   
OpenProcessToken          得到进程的令牌句柄
LookupPrivilegeValue          查询进程的权限
AdjustTokenPrivileges          判断令牌权限  

查看更多...

Tags: 代码 api 调试

分类:破解调试 | 固定链接 | 评论: 0 | 查看次数: 6240

windows启动以及exe文件的加载简介

 先来看这样一个过程(非VISTA启动):CPU复位->传统BIOS->MBR->引导扇区->NTLDR->NTOS->SMSS->1:CSRSS 2:WinLogon->1:LSRSS 2:Services 3:LogonUI->2:Services->Svchost  3:LogonUI->USERINT->1:StartUp App 2:Shell

     这是非 VISTA 的启动过程,是传统 Windows 的启动,这里有几处必要提到,首先 NTLDR 是一个非常重要的启动文件,在 C 盘下,相关的还有 boot.ini, pagefile.sys, NTDETECT.COM,我们按 F8 或者 F5 时进入安全模式的界面也是它产生的。然后是 NTOSKEL 这就是产生滚动条界面的,这是启动最漫长的过程!我曾经看到过有“高手”说过可以改掉滚动条滚动次数的注册表位置,其实这是不能改的,在这个界面下的过程非常漫长非常复杂,不提。然后是 SMSS 进程,这是第一个真正意义上由 .EXE 产生的进程。然后建出 CSRSS 子系统服务器进程和 WinLogon 进程。最后建出 Shell:Explorer.exe 进程。和本文最相关的就是这个 Shell 了,Shell “命令解释器”它的经典就是 Explorer.exe 。每一个窗口其实就是它创建的一个线程!这是一个非常厉害的多线程设计了!比如我们点击桌面上的图标启动一个程序,就是由它来加载创建的,好了,有了这些就开始来讲本文的其中一个内容:.EXE 的加载过程,然后再由此扩充开。

      双击一个 .EXE 图标(操作系统怎么定位哪一个图标不是本文的内容),Shell 调用 CreateProcess 函数,系统找出在调用 CreateProcess 函数时的 .exe 文件,如果文件不在则返回 FALSE 进程创建失败。成功的话则为该进程创建一个新进程内核对象,这个内核对象是由系统内核管理的,关于内核对象也是一个很长的话题,详细叙述的话我写到明天恐怕都写不完这篇文章了,只要知道这个时候如果 CreateProcess 成功的话系统为这个进程创建了一个使用记数为1的进程内核对象,值得一提的是有一个进程内核对象句柄表,这里纪录了所有在该进程中所有创建出来的进程内核对象,但这个东西 Microsoft 没有提供相关文档,我的偶像 Jeffrey Richter 也只是简单的提了一提,接下来系统为这个新进程创建了一个私有地址空间,这就是我们很清楚的 4GB 地址空间! 写到这里先停住,我发现了一个比较大的问题,Shell 调用 CreateProcess 这个函数时其中的参数是哪里来的?我根据 Jeffrey Richter 的一句话也就是系统找出 EXE 文件,如果存在的话则创建成功,那么我进一步推论,那其中的参数很有可能是来自 PE 格式中的信息,可以继续推论下去,研究一下 CreateProcess 的参数再对照一下 PE 格式各个段的包含信息,那应该可以研究出某些东西来,这个细节我是还没有深入对比过,如果有哪位看官知道的话还请赐教!在这里先谢过了!接下来系统会保留一个足够大的区域来存放.exe 文件,默认的话是保存在从OXOO4OOOOO开始的位置,而这个数值是在 exe 这个 PE 结构中的信息,用 /BASE 是可以改的。这里就牵涉到内存映射文件了,不提。我们来研究一下 0X00400000 在内存中的什么区域,看一下 Win32 内存结构中4GB的划分(不再提 98 那破烂了)0x00000000 - 0x0000FFFF 这64KB用于 NULL 指针分配,举一个 Richter 的例子:int *pnSomeInteger = (int*)malloc(sizeof(int)); *pnSomeInteger = 5; 如果 malloc 不能找到足够的内存来分配的话那它就返回 NULL 就是保存在这里了,接下来 0x00010000 - 0x7FFEFFFF 这一段就是 Win32 进程私有的地址空间,刚才的.exe 加载就在这一段空间中,接下来继续加载程序执行所必须的 DLL 文件也是在这个段里,当然在这里还有一些数据需要加载,和为线程开辟的堆栈区,所以进程的这个用户区其实分成了3个部分:文本区包括指令和可读的数据,通常这个段是标记为可读,数据区,这个段对应 PE 中的 DATA_BASS 包含以初始化和未初始化的数据,静态变量也存放在这个区中,最后就是堆栈区,这是为线程分配的默认为1MB,当然是可以改的,在这里包含了函数参数和局部变量,当然也有现场保护时的信息,很关键的一点是 IP 指针也在这里,缓冲区溢出攻击就是在这个区域做文章,俗称:践踏堆栈。好!因为 Win32 中进程是一个惰性的,它什么也不执行,除了 EXE 和 DLL 还有它们所需的数据加载到进程地址空间外每个进程还拥有别的资源,这里只要记住:窗口和钩子是属于线程的外其他都是进程的,所以进程必须有一个线程来执行它的代码,这时候系统就为进程创建一个主线程,但它是调用 C 运行时库函数,这里又有区分 CUI 和 GUI,ANSI 和 UNIODE 的差别,如果以 GUI 和 UNICODE 来讲,它调用的是 wWinMainCTRStartup 这个可执行文件的启动函数。这个函数的功能不多讲,它会进行一系列初始化工作,完了后它将调用我们编写的主函数入口函数比如 wWinMain();最后 exit 调用调用操作系统的ExitProcess 函数,将 nMainRetVal 传递给它,这使得操作系统能够撤销进程并设置它的 exit  代码。到这里启动过程结束!

查看更多...

分类:破解调试 | 固定链接 | 评论: 0 | 查看次数: 8746

调试工具debug的用法

有不少朋友来信问过我这样一个问题: 怎样才能成为一名优秀的HACKER。我的回答是: 深入的了解汇编知识,学好DEBUG的用法。这次借Pc life的一角之地,我将详细的讲解一下DEBUG的用法。
DEBUG是一个DOS实用程序,是供程序员使用的程序调试工具,可以用它检查内存中任何地方的字节以及修改任何地方的字节.它可以用于逐指令执行某个程序以验证程序运行的正确性,也可以追踪执行过程、比较一个指令执行前后的值以及比较与移动内存中数据的范围,读写文件与磁盘扇区。
DEBUG把所有数据都作为字节序列处理。因此它可以读任何类型的文件。DEBUG可以识别两种数据: 十六进制数据和ASCⅡ码字符。它的显示格式是各个字节的十六进制值以及值在32与126之间的字节的相应ASCⅡ码字符。
在DEBUG中输入数据有两种方法: 提示方法和非提示方法。在用提示方法时,用户可以输入要求输入数据的命令,后跟数据所要输入的地址。然后用户就可以看到该地之中已有内容及一个冒号提示符。此时用户可以在提示符下输入一个新的值或者按下回车键或CTRL+C回到短横(-)提示符。在运用非提示方法时,用户可以输入要输入数据的内存地址以及要输入的字节。但与使用字处理程序或正文编辑程序时不一样,在使用DEBUG时,用户不能直接移动光标到一入口点输入或修改数据,而要一次输入一个或几个字节。
在使用DEBUG时可以只涉及内存中的数据,从而一般都要指定所要处理的内存地址,地址的输入格式是: [段地址]: [位移]。如果没有输入地址,DEBUG将假定为当前内存段,从位于地址100H的字节开始。前100H字节保留给程序段前缀使用,这一专用区域用于建立DOS与程序之间的联系。DEBUG总是用四位十六进制数表示地址。用两位数表示十六进制数据。

查看更多...

分类:破解调试 | 固定链接 | 评论: 0 | 查看次数: 9536

Windows下常见进程解析

进程名      描述 
  smss.exe     Session Manager 
  csrss.exe     子系统服务器进程 
  winlogon.exe   管理用户登录 
  services.exe   包含很多系统服务 

查看更多...

分类:破解调试 | 固定链接 | 评论: 0 | 查看次数: 6124
序言:

本学期我承担了07级计科两个班的《软件工程》和08级计科的《C语言程序设计》两门课程的教学任务。在教学过程中,除了对一些基本教学方法和教学技巧的研究和思考以外,我特别关注了金融危机对计算机专业学生就业的影响,以及对大学计算机教育目的、培养方式等一系列问题的思考。这些问题必将对计算机教学产生积极的促进作用。   

一、计算机专业学生就业现状

查看更多...

分类:智慧人生 | 固定链接 | 评论: 0 | 查看次数: 6116

修改PE中的函数为导出函数

1、前言:为什么要这么做
  很多时候,我们发现一个PE(EXE或DLL)中非常有用且功能独立的函数(call xxxxxxxx),并且已经知道了这个函数的各个入口参数的类型和具体含义,我们想在其他的软件中使用这个函数。于是,我想到了将这个PE中的函数改成一个导出函数,这样,我们就可以在任何软件中通过“LoadLibrary("ThisPE.EXE")”等API来使用这个函数了。

2、技术基础:已经了解PE结构

查看更多...

分类:破解调试 | 固定链接 | 评论: 0 | 查看次数: 6350

壳的介绍以及脱壳常用思路

一、概论

壳出于程序作者想对程序资源压缩、注册保护的目的,把壳分为压缩壳和加密壳两种
UPX ASPCAK TELOCK PELITE NSPACK ...
ARMADILLO ASPROTECT ACPROTECT EPE SVKP ...

查看更多...

分类:破解调试 | 固定链接 | 评论: 0 | 查看次数: 4751
熬夜是很正常的事,但经常熬夜对身体会产生很坏的影响,无意中看到这篇文章,转载过来,或许对经常熬夜的同行们会有所帮助。


  睡觉的诀窍­

查看更多...

分类:智慧人生 | 固定链接 | 评论: 1 | 查看次数: 5160

进程PEB结构的修改实现

作者:Gxter

关于进程PEB结构前辈们给出了几篇比较详细的文章。
例如:
《JIURL玩玩Win2k进程线程篇 PEB》

查看更多...

分类:破解调试 | 固定链接 | 评论: 0 | 查看次数: 6738
我相信大家在用OD的过程中也早已发现,如果不使用Create_SUSPENDED,初始化线程在跑到入口点后,其ebx同样指向PEB结构。 

显然,我们必须进入Win32系统新进程创建的过程来找这个真相。由于我们知道初始化线程被创建后(尚未Resume)ebx就已经指向PEB了,所以要不然就是在NtCreateThread过程中,要不然就是在它前面。同时也应该在NtCreatePeb之后。因此我就在这个范围内找寻。 

应该说这里我犯了个错误,就是没有详细看CreateProcess的流程,而是使劲往NtCreateThread的内核代码看去,N多函数调用关系看得我眼花,虽然这些内核函数对线程的Context有诸多操作,但是均并不涉及其Ebx。 

查看更多...

分类:破解调试 | 固定链接 | 评论: 0 | 查看次数: 5726

c语言rar,zip无损压缩算法实现

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

  *                                 *

  *HUFF.C Huffman encode for multimedia application 8*8 pixel Ver 3 *

查看更多...

Tags: c语言Rar 无损压缩 zip压缩

分类:c/c++ | 固定链接 | 评论: 0 | 查看次数: 7747

反汇编驱动常用结构体

typedef struct _DEVICE_OBJECT {
    CSHORT Type; 0x00
    USHORT Size; 0x02
    LONG ReferenceCount; 0x04
    struct _DRIVER_OBJECT *DriverObject; 0x08

查看更多...

分类:内核探究 | 固定链接 | 评论: 0 | 查看次数: 5912

fs寄存器及kernel32.dll地址的获取

FS寄存器指向当前活动线程的TEB结构(线程结构)
偏移 说明
000 指向SEH链指针
004 线程堆栈顶部
008 线程堆栈底部

查看更多...

分类:破解调试 | 固定链接 | 评论: 0 | 查看次数: 5901
  • 1
博主QQ: 友情链接请找我
QQ群: 灰色档案
返回顶部 关闭