首页
论坛
课程
招聘
雪    币: 215
活跃值: 活跃值 (15)
能力值: ( LV9,RANK:410 )
在线值:
发帖
回帖
粉丝

[系统底层] [原创]SEH记录小工具

2007-9-30 04:49 10468

[系统底层] [原创]SEH记录小工具

2007-9-30 04:49
10468
(本文章纯属虚构,如有雷同纯属巧合)

   这个SEH记录小工具是学习脱壳时的“副产品”。大多数加密壳都少不了用SEH进行反跟踪、反调试,不过前辈们说过“这些连续的SEH给调试者指明了一条通往正确目标的道路”,所以对一个壳的SEH了解应该是比较必要的。但是在OD上不断重复重复再重复地“shift+F9”毕竟是一件比较烦人的事,所以就写了这个小工具,让其自动记录SEH发生异常的地址以及其对应的Handler地址,这样一下子就能知道第几个SEH后就开始处理输入表、第几个SEH后就会跳到OEP,直达代码核心,还能根据Handler地址正确设置断点,这样“Shift+F9”就保证不会跑飞。好,废话少说,下面跟大家来分享。

一,一个脱壳实例
    看雪学院编著的《软件加密技术内幕》第三章第二节有一个Hying前辈写的tElock0.98脱壳机源码,KANXUE编著的《加密与解密(第二版)》第十一章第七节脱壳实例有两个用tElock0.98加了壳的样本,分别是Note_tElock.exe、No-Anti.exe。然后用Hying前辈写的脱壳机去脱这两个壳,Note_tElock.exe脱壳成功,No-Anti.exe脱壳失败。
    这个脱壳机会在第16次SEH时候设置断点保护输入表,第20次SEH时候DUMP文件。用SEHstat.exe(附件中)打开Note_tElock.exe及No-Anti.exe,很快就生成两份SEH数据。如下:
    ----------------------------------------------------------------------------------------------
    Note_tElock.exe
    ImageBase:00400000h  StartAddress:0040DBD6h ProcessId:1256 ThreadId:388
    ...
    ---------------------------------main start-----------------------------------
    Exception 01 Address:0040DA1Dh(-441) Handler:0040DA0E(-456) ExcptionCode:EXCEPTION_SINGLE_STEP
    Exception 02 Address:0040DA74h(-354) Handler:0040DA58(-382) ExcptionCode:EXCEPTION_SINGLE_STEP
    Exception 03 Address:0040C08Ch(-6986) Handler:0040C0C5(-6929) ExcptionCode:EXCEPTION_BREAKPOINT
    Exception 04 Address:0040C090h(-6982) Handler:0040C0C5(-6929) ExcptionCode:EXCEPTION_SINGLE_STEP
    Exception 05 Address:0040C099h(-6973) Handler:0040C0C5(-6929) ExcptionCode:EXCEPTION_SINGLE_STEP
    Exception 06 Address:0040C09Eh(-6968) Handler:0040C0C5(-6929) ExcptionCode:EXCEPTION_SINGLE_STEP
    Exception 07 Address:0040C0A3h(-6963) Handler:0040C0C5(-6929) ExcptionCode:EXCEPTION_SINGLE_STEP
    Exception 08 Address:0040C0A7h(-6959) Handler:0040C0C5(-6929) ExcptionCode:EXCEPTION_INT_DIVIDE_BY_ZERO
    Exception 09 Address:0040C6A8h(-5422) Handler:0040C68A(-5452) ExcptionCode:EXCEPTION_ILLEGAL_INSTRUCTION
    Exception 10 Address:0040CAA1h(-4405) Handler:0040CA90(-4422) ExcptionCode:EXCEPTION_INT_DIVIDE_BY_ZERO
    Exception 11 Address:0040CAE4h(-4338) Handler:0040CAC2(-4372) ExcptionCode:EXCEPTION_SINGLE_STEP
    Exception 12 Address:0040CB27h(-4271) Handler:0040CB03(-4307) ExcptionCode:EXCEPTION_BREAKPOINT
    Exception 13 Address:0040CB67h(-4207) Handler:0040CB41(-4245) ExcptionCode:EXCEPTION_INT_DIVIDE_BY_ZERO
    Exception 14 Address:0040CBA6h(-4144) Handler:0040CB84(-4178) ExcptionCode:EXCEPTION_ACCESS_VIOLATION
    Exception 15 Address:0040CBF0h(-4070) Handler:0040CBC4(-4114) ExcptionCode:EXCEPTION_BREAKPOINT
    Exception 16 Address:0040CE0Dh(-3529) Handler:0040CDFE(-3544) ExcptionCode:EXCEPTION_SINGLE_STEP
    Exception 17 Address:0040CE49h(-3469) Handler:0040CE2D(-3497) ExcptionCode:EXCEPTION_SINGLE_STEP
    Load Dll   7D590000h C:\WINDOWS\system32\SHELL32.dll
    Load Dll   77F40000h C:\WINDOWS\system32\SHLWAPI.dll
    Load Dll   77180000h C:\WINDOWS\WinSxS\...\comctl32.dll
    Load Dll   5D170000h C:\WINDOWS\system32\comctl32.dll
    Load Dll   76320000h C:\WINDOWS\system32\comdlg32.dll
    Exception 18 Address:0040D6F1h(-1253) Handler:0040D6FF(-1239) ExcptionCode:EXCEPTION_ILLEGAL_INSTRUCTION
    Exception 19 Address:0040D7E1h(-1013) Handler:0040D7D2(-1028) ExcptionCode:EXCEPTION_SINGLE_STEP
    Exception 20 Address:0040D817h(-959) Handler:0040D7FB(-987) ExcptionCode:EXCEPTION_SINGLE_STEP
    ;这里之后程序就运行了
   
    --------------------------------------------------------------------------------------------------
    No-Anti.exe
    ImageBase:00400000h  StartAddress:0040DBD6h ProcessId:1612 ThreadId:1632
    ...
    ---------------------------------main start-----------------------------------
    Exception 01 Address:0040D9FCh(-474) Handler:0040D9ED(-489) ExcptionCode:EXCEPTION_SINGLE_STEP
    Exception 02 Address:0040DA37h(-415) Handler:0040DA1B(-443) ExcptionCode:EXCEPTION_SINGLE_STEP
    Exception 03 Address:0040C08Ch(-6986) Handler:0040C0C5(-6929) ExcptionCode:EXCEPTION_BREAKPOINT
    Exception 04 Address:0040C090h(-6982) Handler:0040C0C5(-6929) ExcptionCode:EXCEPTION_SINGLE_STEP
    Exception 05 Address:0040C099h(-6973) Handler:0040C0C5(-6929) ExcptionCode:EXCEPTION_SINGLE_STEP
    Exception 06 Address:0040C09Eh(-6968) Handler:0040C0C5(-6929) ExcptionCode:EXCEPTION_SINGLE_STEP
    Exception 07 Address:0040C0A3h(-6963) Handler:0040C0C5(-6929) ExcptionCode:EXCEPTION_SINGLE_STEP
    Exception 08 Address:0040C0A7h(-6959) Handler:0040C0C5(-6929) ExcptionCode:EXCEPTION_INT_DIVIDE_BY_ZERO
    Exception 09 Address:0040C6A8h(-5422) Handler:0040C68A(-5452) ExcptionCode:EXCEPTION_ILLEGAL_INSTRUCTION
    Exception 10 Address:0040CAA1h(-4405) Handler:0040CA90(-4422) ExcptionCode:EXCEPTION_INT_DIVIDE_BY_ZERO
    Exception 11 Address:0040CAE4h(-4338) Handler:0040CAC2(-4372) ExcptionCode:EXCEPTION_SINGLE_STEP
    Exception 12 Address:0040CDF0h(-3558) Handler:0040CDE1(-3573) ExcptionCode:EXCEPTION_SINGLE_STEP
    Exception 13 Address:0040CE28h(-3502) Handler:0040CE0C(-3530) ExcptionCode:EXCEPTION_SINGLE_STEP
    Load Dll   7D590000h C:\WINDOWS\system32\SHELL32.dll
    Load Dll   77F40000h C:\WINDOWS\system32\SHLWAPI.dll
    Load Dll   77180000h C:\WINDOWS\WinSxS\...\comctl32.dll
    Load Dll   5D170000h C:\WINDOWS\system32\comctl32.dll
    Load Dll   76320000h C:\WINDOWS\system32\comdlg32.dll
    Exception 14 Address:0040D6F1h(-1253) Handler:0040D6FF(-1239) ExcptionCode:EXCEPTION_ILLEGAL_INSTRUCTION
    Exception 15 Address:0040D7C8h(-1038) Handler:0040D7B9(-1053) ExcptionCode:EXCEPTION_SINGLE_STEP
    Exception 16 Address:0040D806h(-976) Handler:0040D7EA(-1004) ExcptionCode:EXCEPTION_SINGLE_STEP
    ;这里之后程序就运行了
   
    (说明:Address表示SEH异常发生的地址,Handler表示SEH处理函数的地址,括号里面的数据表示该地址相对程序入口点的偏移,ExcptionCode就是异常类型)
    ---------------------------------------------------------------------------------------------------------
    由上面两份SEH记录很明显可以看出,Note_tElock.exe的SEH很符合Hying前辈的统计数据,所以很顺利就脱了。但是第二份SEH明显就不符合,它总共才发生16次SEH异常而不是20次,在第13次SEH之后就开始处理输入表了,所以这个脱壳机报“locked.exe可能不是TeLock 0.98的外壳。”。
    知道失败原因,我们就可以对源代码进行修改,使它“兼容性”更好一些。由上面数据看来,在本例中根据第几次SEH脱壳可能不是个好主意,我的做法是直接对LoadLibraryA、GetModuleHandleA、VirtualProtectEx下断点(不是INT3哦),当程序第一次执行到LoadLibraryA或GetModuleHandleA时,说明开始处理输入表了,然后在函数返回地址向前80个字节范围内搜索“test  esi, esi;je  ****;”两条指令(不是硬编码偏移值),将函数返回地址直接修改为je ****中的****,这样当LoadLibraryA或GetModuleHandleA执行完毕直接就跳过后面的加密处理代码了(不用修改程序代码哦),而这时的ESI正是原来的输入表地址,可以直接记录下来。当程序执行到VirtualProtectEx时就可以DUMP了(趁PE头还没有被修改),然后大功告成,两个样本程序均能成功脱壳。(附件中有这个tElock0.98_Unpacker.exe)

二、SEH记录小工具的实现
lea ebx,DBEvent.u       
       .while TRUE
       	
       	      invoke WaitForDebugEvent,addr DBEvent,INFINITE
       	      
       	      mov dwDebugOperation,DBG_CONTINUE
       	      
       	      .if DBEvent.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT       ;进程结束       	      	    
                    ...       	      	     
       	      .elseif DBEvent.dwDebugEventCode == CREATE_PROCESS_DEBUG_EVENT ;进程创建
       	              
       	              assume ebx:ptr CREATE_PROCESS_DEBUG_INFO
       	              
       	              mov eax,[ebx].lpStartAddress
       	              mov dwStartAddress,eax       	              
       	              ...
       	              invoke _SetBreakPoint,pi.hProcess,dwStartAddress,addr pOldStartAddressCode ;在程序入口点设置INT3断点      
       	              
       	      .elseif DBEvent.dwDebugEventCode == EXIT_THREAD_DEBUG_EVENT    ;线程结束
       	              ...       	              
       	      .elseif DBEvent.dwDebugEventCode == CREATE_THREAD_DEBUG_EVENT  ;线程创建
       	      	      ...       	      	      
       	      .elseif DBEvent.dwDebugEventCode == LOAD_DLL_DEBUG_EVENT       ;DLL装载
       	      	      
       	      	      assume ebx:ptr LOAD_DLL_DEBUG_INFO
       	      	      
       	      	      invoke ReadProcessMemory,pi.hProcess,[ebx].lpImageName,addr pTempBuffer,4,NULL
       	      	      mov eax,dword ptr pTempBuffer
       	      	      invoke ReadProcessMemory,pi.hProcess,eax,addr pDllName,256,NULL
       	      	      ...
       	      	      
       	      .elseif DBEvent.dwDebugEventCode == UNLOAD_DLL_DEBUG_EVENT     ;DLL卸载
       	      	      ...       	      	             	      	      
       	      .elseif DBEvent.dwDebugEventCode == EXCEPTION_DEBUG_EVENT       ;进程异常	     
       	      	      
       	      	      assume ebx:ptr EXCEPTION_DEBUG_INFO
       	      	      
       	      	      mov dwDebugOperation,DBG_EXCEPTION_NOT_HANDLED ;对不是预期的异常 通通都不处理
       	      	      
       	      	      invoke _GetExceptionText,[ebx].pExceptionRecord.ExceptionCode,addr szExceptionText
       	      	      
       	      	      .if [ebx].pExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT
       	      	      	      
       	      	      	      .if bFirstBreakPoint == 1 ;第一次系统断点       	      	      	             
       	      	      	             invoke lstrcat,addr szExceptionText,addr szNtdllBreakPoint           	      	      	     

        
       	      	      	             mov dwDebugOperation,DBG_CONTINUE ;继续执行  	      	      	             
       	      	      	             mov bFirstBreakPoint,0       	      	      	             
       	      	      	      .endif
       	      	      	      
       	      	      	      mov eax,[ebx].pExceptionRecord.ExceptionAddress
       	      	      	      
       	      	      	      .if eax == dwStartAddress  ;在程序入口点中断 记录一下
       	      	      	      	     
       	      	      	      	     invoke _CleanBreakPoint,pi.hProcess,dwStartAddress,offset pOldStartAddressCode ;清除INT3断点
       	      	      	      	     invoke _ContinueExecute,pi.hThread,dwStartAddress ;INT3之后需要修改EIP
       	      	      	      	     mov dwDebugOperation,DBG_CONTINUE ;继续执行  
       	      	      	      	     
       	      	      	      	     invoke _Hide,pi.hProcess,pi.dwThreadId ;隐藏调试器,目前只能防止IsDebuggerPresent检测 :-)
       	      	      	      	     
       	      	      	      	     invoke _AddRecord,addr szMain
       	      	      	      	     jmp @MyBreakPoint       	      	      	      	     
       	      	      	      	     
       	      	      	      .endif
       	      	      	     
       	      	      .endif       	     	                  	      
       	      	      
                      ;除了自己设置的程序入口断点,其他的异常就开始记录
       	      	      invoke _FindSEHHandler,pi.hProcess,DBEvent.dwThreadId ;查找SEH处理函数地址
       	      	      mov edi,eax
       	      	      mov esi,edi
       	      	      sub esi,dwStartAddress ;计算相对程序入口点偏移
       	      	      
       	      	      mov eax,[ebx].pExceptionRecord.ExceptionAddress ;异常发生地址
       	      	      mov edx,eax
       	      	      sub edx,dwStartAddress ;计算相对程序入口点偏移
       	      	      
       	      	      invoke wsprintf,addr pTempBuffer,addr szExceptionInfo,nExceptionCounter,eax,edx,edi,esi,addr szExceptionText
       	      	      invoke _AddRecord,addr pTempBuffer    ;把记录写到文件中去  	      	
       	      	      
       	      	      inc nExceptionCounter    ;SEH计数器
       	      	      
       	      	      @MyBreakPoint:    
       	      	             	      	              	      	     
       	      .endif       	      
       	      
       	      invoke ContinueDebugEvent,DBEvent.dwProcessId,DBEvent.dwThreadId,dwDebugOperation      	              	
       	
       	
       .endw

       上面是调试主循环的代码,很简单。在程序创建完毕时对程序入口点设置断点,然后在主程序入口点中断时,提示一下主程序已经开始执行了,并进行调试器隐藏。

;查找异常处理函数所在地址
_FindSEHHandler proc uses esi edi ebx hProcess,dwThreadID
	
	LOCAL Teb:DWORD,SEHPtrAddress:DWORD
	
	invoke _FindTeb,dwThreadID ;查找该线程对应的Teb
	.if eax == FALSE
		mov eax,-1
		jmp @ExitFindSEHHandler
	.endif
	mov Teb,eax
	
	invoke ReadProcessMemory,hProcess,Teb,addr SEHPtrAddress,4,NULL ;获取当前SEH handler指针所在地址
	invoke ReadProcessMemory,hProcess,SEHPtrAddress,addr pTempBuffer,8,NULL ;获取当前EXCEPTION_REGISTRATION结构
		
	mov eax,dword ptr [pTempBuffer+4] ;得到SEH handler	
	
	
  @ExitFindSEHHandler:
	ret

_FindSEHHandler endp

       上面查找异常处理函数所在地址,也很简单。TEB的开始地方就是当前SEH链的EXCEPTION_REGISTRATION结构地址,EXCEPTION_REGISTRATION的第二部分就是SEH处理函数的地址。

;查找线程TEB
_FindTeb proc uses esi edi ebx dwThreadID
	
	LOCAL hThread:HANDLE,SelectorEntry:LDT_ENTRY
	
	invoke OpenThread,THREAD_ALL_ACCESS,FALSE,dwThreadID
	.if eax == FALSE
		jmp @ExitFindTeb
	.endif	
	mov hThread,eax
	
	invoke GetThreadContext,hThread,addr Context
	invoke GetThreadSelectorEntry,hThread,Context.regFs,addr SelectorEntry
	
        mov     edx, dword ptr [SelectorEntry.BaseLow]
        and     edx, 0FFFFh
        mov     eax, dword ptr [SelectorEntry.HighWord1.Bytes]
        and     eax, 0FFh
        shl     eax, 10h
        or      edx, eax
        mov     ecx, dword ptr [SelectorEntry.HighWord1.Bytes+3]
        and     ecx, 0FFh
        shl     ecx, 18h
        or      edx, ecx
        mov     ebx, edx
	
        invoke CloseHandle,hThread
       
        mov eax,ebx	
	
  @ExitFindTeb:
	ret

_FindTeb endp

    这上面短短十几行代码,却费了我最多时间。获取线程TEB地址,一开始就想到KTHREAD结构,但是这个结构要在ring0下才能访问,为这个小小程序写一个SYS并要考虑系统兼容性的话,真是杀鸡用牛刀了。后来想起fs:[0]就是TEB地址,即是FS段基地址。由于对保护模式内存管理还是云里雾里,根本不知怎么把FS寄存器选择器数据转为虚拟内存地址,后来跟踪OD才知道原来有GetThreadSelectorEntry这个函数,于是顺便把里面的代码拿过来用,再后来Google GetThreadSelectorEntry,原来网上有不少现成代码(以TEB为关键词却搜不到,奇怪)

;隐藏调试器 但只能防止IsDebuggerPresent检测 :-)
_Hide proc uses esi edi ebx hProcess,dwThreadID
	
	LOCAL pPatch:BYTE
	
	invoke _FindTeb,dwThreadID
	.if eax == FALSE
		jmp @ExitHide
	.endif
	
	add eax,30h  ;fs 30h偏移 就是PEB		
        
        invoke ReadProcessMemory,hProcess,eax,addr pTempBuffer,4,NULL
        
        mov edx,dword ptr pTempBuffer ;这里就是PEB啦        
        add edx,2  ;PEB+2->BeingDebugged 
        
        mov pPatch,0
        
        invoke WriteProcessMemory,hProcess,edx,addr pPatch,1,NULL ;BeingDebugged 项置0
	
	
  @ExitHide:
	ret

_Hide endp

   这段代码也很简单,找到目标进程的PEB.BeingDebugged直接patch。都是_FindTeb这个函数的功劳啊,让查找其他进程PEB的工作变得Very very easy!
上传的附件:
最新回复 (16)
雪    币: 299
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
heimei 活跃值 2007-9-30 05:13
2
0
很强大
雪    币: 1397
活跃值: 活跃值 (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
logkiller 活跃值 2007-9-30 06:46
3
0
LZ真是牛人,支持了。。。
雪    币: 276
活跃值: 活跃值 (10)
能力值: ( LV9,RANK:850 )
在线值:
发帖
回帖
粉丝
大菜一号 活跃值 21 2007-9-30 08:00
4
0
呃,被某人先写了,我来支持鸟。。。。
雪    币: 2
活跃值: 活跃值 (10)
能力值: ( LV12,RANK:250 )
在线值:
发帖
回帖
粉丝
wangdell 活跃值 6 2007-9-30 08:51
5
0
好东西。支持
雪    币: 232
活跃值: 活跃值 (10)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
firefly 活跃值 4 2007-9-30 10:07
6
0
学习了,努力学习脱壳。
雪    币: 1876
活跃值: 活跃值 (10)
能力值: (RANK:500 )
在线值:
发帖
回帖
粉丝
hawking 活跃值 12 2007-9-30 10:40
7
0
天才就是天才......
雪    币: 1
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
DW_DLL 活跃值 2007-9-30 11:00
8
0
堕落终于又看见你了
雪    币: 167
活跃值: 活跃值 (23)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
方向感 活跃值 2007-9-30 12:59
9
0
如何修改楼主提供的源代码成一个loader啊?
运行这个小工具记录软件运行情况,得到日志文件“SEH.txt”:
Unload Dll 77B90000h
Load Dll   75E60000h C:\WINDOWS\system32\apphelp.dll
Load Dll   4DC30000h C:\WINDOWS\system32\msctfime.ime
Load Dll   73B30000h C:\WINDOWS\system32\dciman32.dll
Unload Dll 047E0000h
Load Dll   047E0000h C:\Program Files\GraphicsEditor\Flex.License.Common.dll
Load Dll   71BB0000h C:\WINDOWS\system32\WSOCK32.dll


如何在楼主的代码中加点新功能啊:
.elseif DBEvent.dwDebugEventCode == LOAD_DLL_DEBUG_EVENT       ;DLL装载
       	      	      
     assume ebx:ptr LOAD_DLL_DEBUG_INFO
       	      	      
     invoke ReadProcessMemory,pi.hProcess,[ebx].lpImageName,addr pTempBuffer,4,NULL
     mov eax,dword ptr pTempBuffer
     invoke ReadProcessMemory,pi.hProcess,eax,addr pDllName,256,NULL
     invoke _W2A,addr pDllName ;宽字符转ANSI
       	;--->加入下面加入点新功能,判断动态装载的DLL是指定的DLL后,根据DLL的基址和偏移地址在内存中打补丁,写入新数据.附件是一个现成的内存补丁源代码,但是那个代码只能修改主程序,不能修改动态加载的DLL内存数据(主要是获取不到DLL的基址),dUP的位置偏移和搜索、替换功能做出的loader也不行。      	      
       	.if pDllName == "C:\Program Files\GraphicsEditor\Flex.License.Common.dll"    	  ;汇编不会写:(    	             
       	 
       	 
       	    invoke Sleep,500        ;sleep 500 ms to be unpacked and displayed
            invoke SuspendThread,PI.hProcess    ;suspend the process
            invoke WriteProcessMemory,PI.hProcess,42b448h,addr Bytes,5,addr NBW         ;write new bytes 

       	      	      	             
       	.endif
       	;<---到这里       	      	      
     invoke wsprintf,addr pTempBuffer,addr szLoadDllInfo,[ebx].lpBaseOfDll,addr pDllName
     invoke _AddRecord,addr pTempBuffer      	      	      
       	      	      
.elseif DBEvent.dwDebugEventCode == UNLOAD_DLL_DEBUG_EVENT     ;DLL卸载


能修改主程序的loader源代码:
上传的附件:
雪    币: 201
活跃值: 活跃值 (10)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
angeljyt 活跃值 3 2007-9-30 13:24
10
0
雪    币: 200
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
deepwater 活跃值 2007-10-1 09:32
11
0
楼主实现的是原理就是调试事件, 其实做一个od 插件应该可以得到, 而且具有进一步扩展使用其各种资源的可能.
  如果od 脚本本身能够提供接口, 通过脚本获取就更好了. 不过这个需要脚本方的支持.
  代码中 SelectorEntry.HighWord1.Bytes 不知道哪里看到有这样的成员的, 我没有查到有
HighWord1 成员, 是有意为之?
  另外目的获取teb 地址, 其实直接通过fs:[offset] 就可以访问整个段了, 根本不需要获取地址的.
  对于 GetThreadSelectorEntry的使用, 其实不需要查看它内部或者别人代码,  这些不是密码,都是intel 体系的规范, 了解这个才是根本而且所获甚多.
雪    币: 215
活跃值: 活跃值 (15)
能力值: ( LV9,RANK:410 )
在线值:
发帖
回帖
粉丝
堕落天才 活跃值 10 2007-10-1 18:40
12
0
多谢你看完这篇文章,多谢你的回复,确实用OD插件甚至OD脚本都能完成,至于用哪个是个人喜欢而已。LDT_ENTRY结构我是用RadAsm里面定义的,没有错。另外 fs:[offset]是对应本进程本线程来说的,不同的进程甚至不同的线程FS基地址都不相同,你总不会认为直接fs:[offset]可以访问其他线程的TEB?
雪    币: 200
活跃值: 活跃值 (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
ziyihou 活跃值 1 2007-10-6 16:22
13
0
下了东西,表示下感谢
雪    币: 200
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
chenyh 活跃值 2007-10-9 10:58
14
0
牛人寫的軟件啊
來學習下:D
雪    币: 229
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
binglan212 活跃值 2007-10-9 11:02
15
0
牛人!佩服之至
雪    币: 200
活跃值: 活跃值 (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
paldos_cn 活跃值 1 2007-10-9 13:56
16
0
回头用下,感谢
雪    币: 200
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ynboyinkm 活跃值 2007-10-9 22:07
17
0
下了好东西当然要有丁`
游客
登录 | 注册 方可回帖
返回