能力值:
( LV8,RANK:130 )
|
-
-
2 楼
cmp word ptr[eax],'ZM'
sub eax,1000h
jnz _step1
add eax,3ch
cmp dword ptr[eax],00004550
jnz _step1
自己跟踪啊,这几行有问题
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
mov eax,[esp]
and eax,0FFFF0000h
_step1:
cmp word ptr[eax],'ZM'
把
and eax,0FFFF0000h
改为
and eax, 0FFFFF000H
试试
|
能力值:
(RANK:410 )
|
-
-
4 楼
.386
.model flat, stdcall
option casemap :none
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
.DATA
szBuff db 50 dup(0)
szTitle db 'Kernel32Base',0
szFormat db '%X',0
.CODE
START:
mov eax,[esp]
and eax,0ffff0000h
_step1:
cmp WORD ptr [eax],'ZM'
jnz _step2
mov edx,eax
add edx,[edx+3ch]
cmp WORD ptr [edx],'EP'
jnz _Exit
invoke wsprintf,offset szBuff,offset szFormat,eax
invoke MessageBox,NULL,offset szBuff,offset szTitle,MB_OK
jmp _Exit
_step2:
sub eax,10000h
cmp eax,70000000h
jb _Exit
jmp _step1
_Exit:
invoke ExitProcess,0
end START
|
能力值:
(RANK:1010 )
|
-
-
5 楼
/******************************************************************
(该方法非常通用基本上在9X/NT/2K/XP/2003都可以使用)
1,获得异常处理函数链表首指针
2,遍历到最后一个节点(该节点有一个指向KERNEL32.DLL引出
函数UnhandlerExceptionFilter的函数指针)
3,获得UnhandlerExceptionFilter函数地址,这个地址并根据
PE可执行文件特征查找出KERNEL32.DLL基址.
********************************************************************/
#include <stdio.h>
#include <conio.h>
__inline __declspec(naked) unsigned int GetKernel32(void)
{
__asm
{
mov esi,fs:[0]
lodsd
FindUnExcept:
cmp [eax],0xffffffff
je FindedUnExcept //如果是异常链的最后一个节点
mov eax,[eax] //如果不是异常链的最后一个节点,则向前遍历
jmp FindUnExcept
FindedUnExcept:
mov eax,[eax+0x04] //获得UnHhndlerExceptFilter函数地址,该函数位于KERNEL32.DLL中.
FindMZ_PE:
and eax,0xffff0000 //根据PE执行文件的64K字节齐特征,加快查找速度
cmp word ptr [eax],'ZM'//根据PE可执行文件头部特征确定是否找到KERNEL32.DLL基址.
jne MoveUp //如果与PE可执行文件头部特征不符,继续则向上查找
mov ebx,[eax+0x3c]
add ebx,eax
cmp word ptr [ebx],'EP'
jne MoveUp //如果与PE可执行文件头部特征不符,继续则向上查找
jmp FindOK //如果与PE可执行文件头部特征相符则认为已经找到了KERNEL32.DLL的基址,并能过eax返回
MoveUp:
dec eax //向上查找
jmp FindMZ_PE
FindOK:
ret
}
}
int main()
{
printf("KERNEL32.DLL:\t%0.8X\n",GetKernel32());
getch();
return 0 ;
}
|
能力值:
( LV4,RANK:50 )
|
-
-
6 楼
谢谢大家的解答 我看看哪种方法适合我
至于这种方法是自己想出来的 可能是不行 我也用OD跟踪过
但是开始还在kernel32领空 后来就没了 所以我想问问是怎么回事 它不是要
在内存中按0x1000对齐吗
|
能力值:
( LV4,RANK:50 )
|
-
-
7 楼
回4楼的: 你的方法我试过 但是在xp2上不行
|
能力值:
( LV4,RANK:50 )
|
-
-
8 楼
参考了北极星的代码后 经过我重写了一下代码 终于能运行了 得到了正确的kernel32基址 呵呵 非常感谢你啊 同时我还更深入了解了seh
|
能力值:
(RANK:410 )
|
-
-
9 楼
最初由 yiyiguxing 发布 回4楼的: 你的方法我试过 但是在xp2上不行
我不清楚你的XP2为什么不行,我的XP2上是可以的。
|
能力值:
( LV8,RANK:130 )
|
-
-
10 楼
代码写错是很正常的,不过为什么不能调试出来自己错在哪里呢?
在这里手工赋值eax=hKernel32,然后单步跟踪,很容易就可以观察到为什么会跑飞的
cmp word ptr[eax],'ZM'
sub eax,1000h
jnz _step1
add eax,3ch
cmp dword ptr[eax],00004550
jnz _step1
|
能力值:
( LV9,RANK:690 )
|
-
-
11 楼
最初由 heXer 发布 代码写错是很正常的,不过为什么不能调试出来自己错在哪里呢? 在这里手工赋值eax=hKernel32,然后单步跟踪,很容易就可以观察到为什么会跑飞的
cmp word ptr[eax],'ZM' sub eax,1000h ........
有道理,不过拿出来讨论
让我学到了知识。:)
|
能力值:
( LV2,RANK:10 )
|
-
-
12 楼
最近闲着,看这贴好兴趣就拿楼主的程序跟跟,跟小虾的比较修改后还可以,请楼主测试
.code
_start:
call delta
delta:
pop ebp
sub ebp,offset delta
mov eax,[esp]
and eax,0FFFF0000h
_step1:
cmp word ptr[eax],'ZM'
;sub eax,10000h
jnz _step2
mov edx,eax
add edx,[edx+3ch]
cmp WORD ptr [edx],'EP'
;add eax,3ch
;cmp dword ptr[eax],00004550
jnz _step1
xor ebx,ebx
push ebx
push offset tit1
push offset msg1
push ebx
call MessageBoxA
jmp _exit
_step2:
sub eax,10000h
;mov eax,edx
jmp _step1
_exit:
xor ebx,ebx
call ExitProcess
end _start
|
能力值:
( LV4,RANK:50 )
|
-
-
13 楼
#pragma comment(linker,"/ENTRY:main")
#pragma warning(disable:4035)
#include<stdio.h>
__forceinline void* GetKernel32()
{__asm{
mov eax,fs:[30h]
mov eax,[eax+0ch]
mov eax,[eax+1ch]
mov eax,[eax]
mov eax,[eax+08h]
}}
void main()
{
printf("KERNEL32.DLL:%08X\n",GetKernel32());
}
===========================================================================================
00401000 >/$ 64:A1 30000000 mov eax,fs:[30] ; Entry Point
00401006 |. 8B40 0C mov eax,[eax+C]
00401009 |. 8B40 1C mov eax,[eax+1C]
0040100C |. 8B00 mov eax,[eax]
0040100E |. 8B40 08 mov eax,[eax+8]
00401011 |. 50 push eax ; /<%08X>
00401012 |. 68 00304000 push 00403000 ; |format = "KERNEL32.DLL:%08X\n"
00401017 |. FF15 00204000 call [<&MSVCRT.printf>]; \printf
0040101D |. 83C4 08 add esp,8
00401020 \. C3 retn
|
能力值:
( LV4,RANK:50 )
|
-
-
14 楼
很高兴看到这么多朋友给我回贴 在此我深表谢意 无以为报 只有更加努力
把自己的小小心得与大家分享
|
能力值:
( LV9,RANK:690 )
|
-
-
15 楼
最初由 dwing 发布 #pragma comment(linker,"/ENTRY:main") #pragma warning(disable:4035) #include<stdio.h> __forceinline void* GetKernel32() {__asm{ ........
这个最简练!
用vc6编译了一下,访问内存出错。
GetKernel32没有inline进去。
---
printf("KERNEL32.DLL:%08X\n",0x77E40000);
这样也出错了。 把//#pragma comment(linker,"/ENTRY:main")
注释后,运行OK。
但仍然没有inline进去。
|
能力值:
( LV4,RANK:50 )
|
-
-
16 楼
最初由 winndy 发布 这个最简练!
用vc6编译了一下,访问内存出错。
GetKernel32没有inline进去。 ........
我想你一定用debug模式编译的.
|
能力值:
(RANK:1060 )
|
-
-
17 楼
加一个判断是不是保险点
mov eax, [esp]
__get_krnl: and eax, 0FFFFF000h
cmp word ptr [eax], 'ZM'
jne __skip
mov ecx, [eax+3Ch]
cmp ecx, 1000h
jg __skip
add ecx, eax
cmp word ptr [ecx], 'EP'
je __cool
__skip: dec eax
jmp __get_krnl
__cool: ; now eax = kernel32 base
|
能力值:
( LV9,RANK:690 )
|
-
-
18 楼
最初由 dwing 发布 我想你一定用debug模式编译的.
我用OD看了realease版的
还是没有inline进去.
我用VC6编译的.
|
能力值:
( LV2,RANK:10 )
|
-
-
19 楼
我还什么都不懂,正在学
|
能力值:
( LV4,RANK:50 )
|
-
-
20 楼
最初由 winndy 发布 我用OD看了realease版的 还是没有inline进去. 我用VC6编译的.
我又试了一次,用VC6+SP6(release)编译,可以inline进去.
|
能力值:
( LV9,RANK:690 )
|
-
-
21 楼
奇怪了
|
能力值:
( LV4,RANK:50 )
|
-
-
22 楼
最初由 winndy 发布 奇怪了
把整个工程目录打包传上来(不需要其中的release/debug目录),我编译一下试试...
|
能力值:
( LV9,RANK:690 )
|
-
-
23 楼
最初由 dwing 发布 把整个工程目录打包传上来(不需要其中的release/debug目录),我编译一下试试...
谢谢你这么热情的跟帖解答.
今天我又仔细看了看,发现我没有好好理解inline的意思.
==realease 模式======
004010F9 |. A1 5C6C4000 MOV EAX,DWORD PTR DS:[406C5C]
004010FE |. A3 606C4000 MOV DWORD PTR DS:[406C60],EAX
00401103 |. 50 PUSH EAX
00401104 |. FF35 546C4000 PUSH DWORD PTR DS:[406C54]
0040110A |. FF35 506C4000 PUSH DWORD PTR DS:[406C50]
00401110 |. E8 EBFEFFFF CALL GetKerne.00401000
......
这里调用__forceinline void* GetKernel32()
按我以前的理解,应该把这段代码直接嵌入到这里,而不是用一个call去调用.
00401000 $ 64:A1 3000000>MOV EAX,DWORD PTR FS:[30]
00401006 . 8B40 0C MOV EAX,DWORD PTR DS:[EAX+C]
00401009 . 8B40 1C MOV EAX,DWORD PTR DS:[EAX+1C]
0040100C . 8B00 MOV EAX,DWORD PTR DS:[EAX]
0040100E . 8B40 08 MOV EAX,DWORD PTR DS:[EAX+8]
00401011 . 50 PUSH EAX
00401012 . 68 30604000 PUSH GetKerne.00406030 ; ASCII "KERNEL32.DLL:%08X
"
00401017 . E8 14000000 CALL GetKerne.00401030
0040101C . 83C4 08 ADD ESP,8
0040101F . E9 423B0000 JMP GetKerne.00404B66
===debug 模式的====
00401080 >/> \55 PUSH EBP
00401081 |. 8BEC MOV EBP,ESP
00401083 |. 83EC 40 SUB ESP,40
00401086 |. 53 PUSH EBX
00401087 |. 56 PUSH ESI
00401088 |. 57 PUSH EDI
00401089 |. 8D7D C0 LEA EDI,DWORD PTR SS:[EBP-40]
0040108C |. B9 10000000 MOV ECX,10
00401091 |. B8 CCCCCCCC MOV EAX,CCCCCCCC
00401096 |. F3:AB REP STOS DWORD PTR ES:[EDI]
00401098 |. 64:A1 3000000>MOV EAX,DWORD PTR FS:[30]
0040109E |. 8B40 0C MOV EAX,DWORD PTR DS:[EAX+C]
004010A1 |. 8B40 1C MOV EAX,DWORD PTR DS:[EAX+1C]
004010A4 |. 8B00 MOV EAX,DWORD PTR DS:[EAX]
004010A6 |. 8B40 08 MOV EAX,DWORD PTR DS:[EAX+8]
004010A9 |. 5F POP EDI
004010AA |. 5E POP ESI
004010AB |. 5B POP EBX
004010AC |. 83C4 40 ADD ESP,40
004010AF |. 3BEC CMP EBP,ESP
004010B1 |. E8 9A000000 CALL GetKerne.__chkesp
004010B6 |. 8BE5 MOV ESP,EBP
004010B8 |. 5D POP EBP
004010B9 \. C3 RETN
能详细解释一下inline吗?
|
能力值:
( LV13,RANK:810 )
|
-
-
24 楼
get_k32base:
pushad
sub eax,eax
mov eax,fs:[eax+30h]
test eax,eax
js @@os_9x
@@os_nt:
mov eax,[eax+0ch]
mov esi,[eax+1ch]
lodsd
mov eax,[eax+8]
jmp @@finished
@@os_9x:
mov eax,[eax+34h]
lea eax,[eax+7ch]
mov eax,[eax+3ch]
@@finished:
mov [esp+4*7],eax
popad
retn
小弟比较喜欢这样..体积短小~~
|
能力值:
( LV4,RANK:50 )
|
-
-
25 楼
有大量内嵌汇编的函数用inline一般是不起作用的,只能__forceinline.
|
|
|