zoukankan      html  css  js  c++  java
  • 定位API地址学习

    采用FS去定位API地址:

    FS寄存器指向当前活动线程的TEB结构(线程结构)
    偏移 说明
    000 指向SEH链指针
    004 线程堆栈顶部
    008 线程堆栈底部
    00C SubSystemTib
    010 FiberData
    014 ArbitraryUserPointer
    018 FS段寄存器在内存中的镜像地址
    020 进程PID
    024 线程ID
    02C 指向线程局部存储指针
    030 PEB结构地址(进程结构)
    034 上个错误号


    mov eax,fs:[0x18]     ; 获得当前线程的TEB地址
    mov eax,[eax+0x30]    ; 在TEB偏移30h获得PEB地址
    
    TIB+18h 是TIB的反身指针  指向PEB的首地址 因此可省略而直接使用fs:[30h] 得到自己进程的PEB

    从XP SP2 引入  不同进程的PEB地址会不一样    所以不能用  本进程的FS:[28H] 的指针去读取其他进程的内容

    如果是用这种方式去获得PEB的话   还要去循环验证是否为 kernel32.dll

    		mov eax,fs:[0x18]    //获得FS段寄存器在内存中的镜像地址,即TEB的地址
    		mov pTeb,eax    
    所以不采用这种方式  在 计算机病毒揭秘  中  去寻找API地址   采用 先找 kernel32.dll  在去找API地址

    FS:0指向线程环境块TEB;
    FS:[0]指向当前线程的结构化异常处理结构(SEH);
    FS:0指向TEB的理解应该是:
    TEB结构存放于FS段从0开始的位置,整个TEB结构数据在FS段中;
    
    FS:[0]指向当前线程的结构化异常处理结构的理解应该是:
    在FS:0所指向的TEB结构中,第一个元素指向当前线程的结构化异常处理结构,而这个结构存在与DS段中;
    
    部分TEB如下:
    
    
    ntdll!_TEB
    struct _TEB, 66 elements, 0xfb8 bytes
       +0x000 NtTib            : struct _NT_TIB, 8 elements, 0x1c bytes
          +0x000 ExceptionList    : Ptr32 to struct _EXCEPTION_REGISTRATION_RECORD,2 elements, 0x8 bytes
             +0x000 Next             : Ptr32 to struct _EXCEPTION_REGISTRATION_RECORD, 2 elements, 0x8 bytes
             +0x004 Handler          : Ptr32 to           _EXCEPTION_DISPOSITION 
          +0x004 StackBase        : Ptr32 to Void
          +0x008 StackLimit       : Ptr32 to Void
          +0x00c SubSystemTib     : Ptr32 to Void
          +0x010 FiberData        : Ptr32 to Void
          +0x010 Version          : Uint4B
    ...........................................
    ............................................
    而下面两条指令可以看出其差异吧:
    
    MOV EAX,FS:0==>EAX=0              (SoftICE中)
    MOV EAX,FS:[0]==>EAX=指向SEH的指针,如0x0012FFB0

    fs:0表示的是fs段中偏移量0这个地址,从这个地址开始储存的就是TEB,程序中不能直接使用fs:0(有些编译器会将其解释为fs:[0])。
    fs:[0]表示的是fs:0这个地址中储存的数据,TEB中的第1个成员就是SEH指针。
    在 masm32 中,fs:0 和 fs:[0] 是完全相同的。  在用之前  用  assume fs:nothing编译器不同导致

    下面是通过扫描 kernel32.dll获得   MessageBoxA   ExitProcess  LoadLibraryA 函数地址   当然 我们可以修改其中的digest  找到 LoadLibraryA  和  GetProcaddress  地址例子:

    int main()
    {	
    	_asm{
    			nop
    			nop
    			nop
    			nop
    			nop
    			CLD					; clear flag DF
    			;store hash
    			push 0x1e380a6a		;hash of MessageBoxA
    			push 0x4fd18963		;hash of ExitProcess
    			push 0x0c917432		;hash of LoadLibraryA   这里添加你想要的函数  EG: LoadLibraryA  GetProcaddress   最后在[EDI-0xX]就是函数的地址   
    			mov esi,esp			; esi = addr of first function hash 
    			lea edi,[esi-0xc]	; edi = addr to start writing function 
    
    			
    
    			; make some stack space
    			xor ebx,ebx
    			mov bh, 0x04 			 
    			sub esp, ebx 
    			
    
    
    			
    			; push a pointer to "user32" onto stack 
    			mov bx, 0x3233 		; rest of ebx is null 
    			push ebx 
    			push 0x72657375 
    			push esp 
    			
    			xor edx,edx
    
    
    		; find base addr of kernel32.dll 
    			mov ebx, fs:[edx + 0x30] 	; ebx = address of PEB 
    			mov ecx, [ebx + 0x0c] 		; ecx = pointer to loader data 
    			mov ecx, [ecx + 0x1c] 		; ecx = first entry in initialisation order list 
    			mov ecx, [ecx] 				; ecx = second entry in list (kernel32.dll) 
    			mov ebp, [ecx + 0x08] 		; ebp = base address of kernel32.dll 
    			
    						
    		find_lib_functions: 
    		
    			lodsd 					; load next hash into al and increment esi 
    			cmp eax, 0x1e380a6a		; hash of MessageBoxA - trigger 
    									; LoadLibrary("user32") 
    			jne find_functions 
    			xchg eax, ebp 			; save current hash 
    			call [edi - 0x8] 		; LoadLibraryA 
    			xchg eax, ebp 			; restore current hash, and update ebp 
    									; with base address of user32.dll 
    			
    			
    		find_functions: 
    			pushad 						; preserve registers 
    			mov eax, [ebp + 0x3c]		; eax = start of PE header 
    			mov ecx, [ebp + eax + 0x78]	; ecx = relative offset of export table 
    			add ecx, ebp 				; ecx = absolute addr of export table 
    			mov ebx, [ecx + 0x20] 		; ebx = relative offset of names table 
    			add ebx, ebp 				; ebx = absolute addr of names table 
    			xor edi, edi 				; edi will count through the functions 
    
    		next_function_loop: 
    			inc edi 					; increment function counter 
    			mov esi, [ebx + edi * 4] 	; esi = relative offset of current function name 
    			add esi, ebp 				; esi = absolute addr of current function name 
    			cdq 						; dl will hold hash (we know eax is small) 
    			
    		hash_loop: 
    			movsx eax, byte ptr[esi]
    			cmp al,ah
    			jz compare_hash
    			ror edx,7
    			add edx,eax
    			inc esi
    			jmp hash_loop
    
    		compare_hash:	
    			cmp edx, [esp + 0x1c] 		; compare to the requested hash (saved on stack from pushad) 
    			jnz next_function_loop 
    			
    		 
    			mov ebx, [ecx + 0x24] 		; ebx = relative offset of ordinals table 
    			add ebx, ebp 				; ebx = absolute addr of ordinals table 
    			mov di, [ebx + 2 * edi] 	; di = ordinal number of matched function 
    			mov ebx, [ecx + 0x1c] 		; ebx = relative offset of address table 
    			add ebx, ebp 				; ebx = absolute addr of address table 
    			add ebp, [ebx + 4 * edi] 	; add to ebp (base addr of module) the 
    										; relative offset of matched function 
    			xchg eax, ebp 				; move func addr into eax 
    			pop edi 					; edi is last onto stack in pushad 
    			stosd 						; write function addr to [edi] and increment edi 
    			push edi 
    			popad					; restore registers 
    					 				; loop until we reach end of last hash 
    			cmp eax,0x1e380a6a
    			jne find_lib_functions 
    
    		function_call:
    			xor ebx,ebx
    			push ebx			// cut string
    			push 0x74736577
    			push 0x6C696166		//push failwest
    			mov eax,esp			//load address of failwest
    			push ebx	
    			push eax
    			push eax
    			push ebx
    			call [edi - 0x04] ; //call MessageboxA
    			push ebx
    			call [edi - 0x08] ; // call ExitProcess
    			nop
    			nop
    			nop
    			nop
    	}
    }
















  • 相关阅读:
    js实现选择切换
    Jquery操作select
    Mybatis 高级结果映射 ResultMap Association Collection
    jQuery的一些特性和用法
    利用JSONP解决AJAX跨域问题的原理与jQuery解决方案
    List转成Array 连个Array比较
    3.15
    Get 和 Post 方法的选择和URL的设计
    fd
    如何维护一个1000 IP的免费代理池
  • 原文地址:https://www.cnblogs.com/zcc1414/p/3982545.html
Copyright © 2011-2022 走看看