首页
社区
课程
招聘
直接执行 函数地址
发表于: 2011-9-16 23:44 13250

直接执行 函数地址

2011-9-16 23:44
13250
7C8021CE      90            nop
7C8021CF      90            nop
7C8021D0 >    8BFF          mov edi,edi                              ;  ReadProcessMemory
7C8021D2      55            push ebp
7C8021D3      8BEC          mov ebp,esp
7C8021D5      8D45 14       lea eax,dword ptr ss:[ebp+0x14]        我要从这里执行
7C8021D8   .  50            push eax
7C8021D9   .  FF75 14       push dword ptr ss:[ebp+0x14]
7C8021DC   .  FF75 10       push dword ptr ss:[ebp+0x10]

不直接调用  ReadProcessMemory  因为有可能被 inline hook 呢。

直接写入参数   然后  转到    ReadProcessMemory+5  这里执行。

我自己写的老出错。。

[课程]Android-CTF解题方法汇总!

收藏
免费 6
支持
分享
最新回复 (33)
雪    币: 1149
活跃值: (833)
能力值: ( LV13,RANK:260 )
在线值:
发帖
回帖
粉丝
2
naked  函数...
2011-9-17 00:36
0
雪    币: 258
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
栈帧没有正确构造,以前看过相同功能的shellcode,好像是这个样子的

push lpNumberOfBytesRead
push nSize
push lpBuffer
push lpBaseAddress
push hProcess;参数压栈
call $+5
pop eax;重定位
add eax, 0x0A
push eax;返回地址压栈
push ebp
mov ebp, esp
jmp ebx; ebx是入口+5
        

其中 0x0A = 1(pop eax) + 3(add eax, 0x0a) + 1(push eax) + 1(push ebp) + 2(mov ebp, esp) + 2(jmp ebx)
2011-9-17 00:36
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
__declspec( naked ) void test(    HANDLE hProcess,    LPCVOID lpBaseAddress,    LPVOID lpBuffer,    DWORD nSize,    LPDWORD lpNumberOfBytesRead)
{

    __asm
    {
   
        
        mov eax,RET
        push eax//压入返回地址

        mov edi,edi
        push ebp
        mov ebp,esp
        mov eax,0x7C8021D5
        jmp eax
RET:
     ret 0x14
    }
}
2011-9-17 00:49
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
__declspec( naked ) void test(    HANDLE hProcess,    LPCVOID lpBaseAddress,    LPVOID lpBuffer,    DWORD nSize,    LPDWORD lpNumberOfBytesRead)
{

    __asm
    {
   
        
        mov eax,RET
        push eax//压入返回地址

        mov edi,edi
        push ebp
        mov ebp,esp
        mov eax,0x7C8021D5
        jmp eax
RET:
     ret 这个不要平衡堆栈了,调用的函数 ReadProcessMemory
平衡堆栈
    }
}
2011-9-17 00:53
0
雪    币: 227
活跃值: (28)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6


运行提示错误。。。。。错误:

0x7C802200 指令引用的 0x0000010 内存。该内存不能为 written。


__declspec( naked ) void test(    HANDLE hProcess,    LPCVOID lpBaseAddress,    LPVOID lpBuffer,    DWORD nSize,    LPDWORD lpNumberOfBytesRead)
{
       
    __asm
    {
        mov eax,JRET
                        push eax//压入返回地址
                       
                        mov edi,edi
                        push ebp
                        mov ebp,esp
                        mov eax,0x7C8021D5
                        jmp eax
JRET:
                ret
    }
}

void main()
{
        char cc[1024] ;

        ReadProcessMemory((LPVOID)-1, (LPVOID)0x400000 , &cc, 1024 , 0);

        test((LPVOID)-1, (LPVOID)0x400000, &cc, 0x10, 0);

        system("pause");
}
2011-9-17 01:03
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
如果你读的是代码执行指令空间,你要用VirtualProtect

VirtualProtect
The VirtualProtect function changes the access protection on a region of committed pages in the virtual address space of the calling process. This function differs from VirtualProtectEx, which changes the access protection of any process.

BOOL VirtualProtect(
  LPVOID lpAddress,    // address of region of committed pages
  DWORD dwSize,        // size of the region
  DWORD flNewProtect,  // desired access protection
  PDWORD lpflOldProtect
                       // address of variable to get old protection
);
2011-9-17 01:13
0
雪    币: 100
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
就是选把要读的指令空间属性设置为可读写
2011-9-17 01:14
0
雪    币: 278
活跃值: (709)
能力值: ( LV15,RANK:520 )
在线值:
发帖
回帖
粉丝
9
7C8021D0 >    8BFF          mov edi,edi                              ;  ReadProcessMemory
7C8021D2      55            push ebp
7C8021D3      8BEC          mov ebp,esp
jmp 0xC8021D0+5
2011-9-17 01:17
0
雪    币: 773
活跃值: (442)
能力值: ( LV9,RANK:200 )
在线值:
发帖
回帖
粉丝
10
__asm
    {
      mov edi,edi
      push ebp
      mov ebp,esp
      mov eax,ReadProcessMemory
      add eax,5      
      jmp eax
    }
不用返回
2011-9-17 01:49
0
雪    币: 227
活跃值: (28)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
不知道为什么。。。

那个函数不好用。。。单次执行啥问题没有,,,但是我大量执行,问题就来了。。总是出错。。大家看看我那里没有写好。

大概执行  5次就会出错。。。

使用   test_ReadProcessMemory   大量执行的时候总出错,,,,但是用   ReadProcessMemory 就没问题。



vodi test_ReadProcessMemory(  HANDLE hProcess,    LPCVOID lpBaseAddress,    LPVOID lpBuffer,    DWORD nSize,    LPDWORD lpNumberOfBytesRead)
{
    __asm
    {
                        mov edi,edi
                        push ebp
                        mov ebp,esp
                        mov eax,ReadProcessMemory
                        add eax,5
                        jmp eax
    }
}

void main()
{
        char cc[0x1024] ;
        int tmpaddr = 0x400000;
       
        while(tmpaddr < 0x7FFFFFFF)
        {
                tmpaddr = tmpaddr + 0x1024;
                test_ReadProcessMemory((LPVOID)-1, (LPCVOID)tmpaddr, (LPVOID)&cc, 1024, 0);
                printf(" %x %x \n" ,  tmpaddr, &cc);
        }
       
        system("pause");
}
2011-9-17 02:02
0
雪    币: 8865
活跃值: (2379)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
12
函数要naked的啊啊啊~~
2011-9-17 05:09
0
雪    币: 113
活跃值: (100)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
13
naked 关键字。__declspec( naked )
2011-9-17 13:29
0
雪    币: 227
活跃值: (28)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14


不行的。。。加上  naked 关键字。__declspec( naked )       一样不行,,,总是出错。。。。有点不明白呢,而且看    printf的输出。。。地址怎么显示的不对
2011-9-17 16:42
0
雪    币: 503
活跃值: (80)
能力值: (RANK:280 )
在线值:
发帖
回帖
粉丝
15
你的代码有几个问题

tmpaddr是带符号整数,所以那个while永远为真,不过这不是那个错误信息的原因
问题可能在&cc上,cc已经是数组了,不需要这个&,有可能是你用的编译器比较老,编译器把&cc编译成了一个独立变量,造成堆栈错误,导致tmpaddr,以及堆栈中的0被重写了,看那个地址似乎是函数在尝试写入lpNumberOfBytesRead
另外还有个不是问题的问题,数组长度一会1024, 一会0x1024,统一起来比较好
2011-9-17 19:10
0
雪    币: 349
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
hProcess
[in] A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process.
不知道是不是这个原因。
2011-9-17 19:13
0
雪    币: 962
活跃值: (1696)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
cc这样写也可以 没什么问题的 不过一般不推荐这样的写法
最关键是没加 __stdcall
2011-9-17 19:25
0
雪    币: 503
活跃值: (80)
能力值: (RANK:280 )
在线值:
发帖
回帖
粉丝
18
拿vc6编译了一下,是堆栈被重写导致的,但前面关于&cc的猜测是错的,而是因为test_ReadProcessMemory是个普通函数,你需要再加一个WINAPI的声明,否则VC6会在函数调用后调整ESP(5个参数,所以加了0x14)

__declspec(naked) WINAPI void test_ReadProcessMemory(  HANDLE hProcess,    LPCVOID lpBaseAddress,    LPVOID lpBuffer,    DWORD nSize,    LPDWORD lpNumberOfBytesRead)

这么写就不会有问题了
2011-9-17 20:00
0
雪    币: 503
活跃值: (80)
能力值: (RANK:280 )
在线值:
发帖
回帖
粉丝
19
你说的没错,前面的猜测是错的
2011-9-17 20:02
0
雪    币: 357
活跃值: (3133)
能力值: ( LV3,RANK:25 )
在线值:
发帖
回帖
粉丝
20
地址空间不可读,那内存根本没分配出来
2011-9-17 21:22
0
雪    币: 227
活跃值: (28)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21

一样的代码

我用 ReadProcessMemory   就可以的。。

但是用 test_ReadProcessMemory   就不行,,,大概循环几次就 出错呢。
2011-9-17 21:32
0
雪    币: 503
活跃值: (80)
能力值: (RANK:280 )
在线值:
发帖
回帖
粉丝
22
因为test_ReadProcessMemory每次调用结束后esp都会增加0x14, 你改成如下声明就没事了

__declspec(naked) WINAPI void test_ReadProcessMemory(  HANDLE hProcess,    LPCVOID lpBaseAddress,    LPVOID lpBuffer,    DWORD nSize,    LPDWORD lpNumberOfBytesRead)
2011-9-17 21:37
0
雪    币: 227
活跃值: (28)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
终于可以了。。感谢楼上所有大虾们。。。我基础太差了。。。

不过加了 WINAPI 就有这个提示。。。编译器提示  不过程序可以正常运行。



__declspec(naked) WINAPI void test_ReadProcessMemory(  HANDLE hProcess,    LPCVOID lpBaseAddress,    LPVOID lpBuffer,    DWORD nSize,    LPDWORD lpNumberOfBytesRead)

Compiling...
tcp.cpp
d:\program files\vc6\myprojects\tcp\tcp.cpp(379) : warning C4518: 'void ' : storage-class or type specifier(s) unexpected here; ignored
d:\program files\vc6\myprojects\tcp\tcp.cpp(379) : warning C4230: anachronism used : modifiers/qualifiers interspersed, qualifier ignored
Linking...

2011-9-17 21:56
0
雪    币: 503
活跃值: (80)
能力值: (RANK:280 )
在线值:
发帖
回帖
粉丝
24
抱歉是我疏忽了,
把void去掉或是放在WINAPI前面
2011-9-17 22:04
0
雪    币: 76
活跃值: (55)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
再次领略乌龟风范!
2011-9-18 23:36
0
游客
登录 | 注册 方可回帖
返回
//