首页
社区
课程
招聘
读取某个时刻下某个寄存器或某个地址的内容
发表于: 2011-3-14 10:56 8824

读取某个时刻下某个寄存器或某个地址的内容

2011-3-14 10:56
8824
我用OD发现一个程序A(关键代码见后)在执行完语句“73D3451B    E8 D4E0FFFF  call <j mp.&msvcrt.memcpy>”后,通过eax返回了一个我比较感兴趣的值,同时,在执行“jmp.&msvcrt.memcpy”时还将这个值送到了内存单元“00342A8”中。
    我想在不修改源程序A的基础上编写另一个程序B,将A执行完“call <j mp.&msvcrt.memc py>”后通过eax返回值读出来,要通过什么技术呢?
    还有,OD支持在相邻的两条语句间插入汇编代码吗?如果支持,我就可以在73D3451B和73D34520之间插入一段代码,将eax的值送到我的程序B中.....但我在OD中没找到这样的功能,请问这个思路能实现吗?要实现我上面说的功能,还有什么方法吗?
73D34518    03C8            add     ecx, eax
73D3451A    51              push    ecx
73D3451B    E8 D4E0FFFF     call    <jmp.&msvcrt.memcpy>
73D34520    8B06            mov     eax, dword ptr [esi]
73D34522    83C4 0C         add     esp, 0C

[课程]Linux pwn 探索篇!

收藏
免费 0
支持
分享
最新回复 (19)
雪    币: 2368
活跃值: (81)
能力值: (RANK:300 )
在线值:
发帖
回帖
粉丝
2
有内存注册机的生成工具,可以做到这一点。
直接修改可以做到。做内存补丁也行。
2011-3-14 11:09
0
雪    币: 93
活跃值: (42)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
谢谢回复!
我不做破解,只是想编写另一个软件获取这个信息,然后再我自己的软件里做一些数据处理。
内存注册机生成工具满足不了要求,直接修改可能会带来程序不稳定的问题,并且用汇编做数据处理与通信工作量太大。内存补丁,额我在查查.......
大家还有其他思路吗?
2011-3-14 13:33
0
雪    币: 93
活跃值: (42)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
还有,可不可以让源程序A跳去执行程序外的一段代码,用高级语言来写这段代码?
2011-3-14 13:53
0
雪    币: 93
活跃值: (42)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
这有一篇代码注入的文章,言简意赅,菜鸟可以来看看,呵呵
http://home.inf.fh-rhein-sieg.de/~ikarim2s/how2injectcode/code_inject.html
2011-3-14 14:48
0
雪    币: 2368
活跃值: (81)
能力值: (RANK:300 )
在线值:
发帖
回帖
粉丝
7
你查一下HOOK ,DLL 注入相关的知识。相信会有些收获
2011-3-14 16:12
0
雪    币: 90
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
不错的问题,收藏一下看看大侠们都怎么解决
2011-3-15 13:38
0
雪    币: 93
活跃值: (42)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
各位,我尝试着直接在OD下修改原程序的汇编代码,但需要在ntdll.dll下加一条Call语句跳到我的exe程序里,而这个dll和我的exe程序是分开的啊,改了保存也不能起到作用,大家是怎么解决这种情况的呢?
2011-3-18 21:20
0
雪    币: 2134
活跃值: (14)
能力值: (RANK:170 )
在线值:
发帖
回帖
粉丝
10
73D34518    03C8            add     ecx, eax
73D3451A    51              push    ecx
73D3451B    E8 D4E0FFFF     call    <jmp.&msvcrt.memcpy>
73D34520    8B06            mov     eax, dword ptr [esi]
73D34522    83C4 0C         add     esp, 0C



73D3451B    E8 D4E0FFFF     call    <jmp.&msvcrt.memcpy>

类似动态内存patch,加载程序,注入dll ,在执行到真正入口点后,把这个call替换为自己的地址,再通过pushad获取当前所有寄存器值到堆栈上,取得你想关注的寄存器,作处理,最后再popad,调用原始memcpy,跳回73D34520即可。
2011-3-19 00:51
0
雪    币: 93
活跃值: (42)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
我按照《加密与解密》的内容做了内存补丁,但这个地址7C922233上的代码在系统DLL里,内存补丁也不能写进去啊!!
    我试验过,即便是用内存补丁工具,也不能修改DLL里的汇编代码(运行dUP制作的path,只显示“补丁运行完毕”,而连原程序都不能加载运行...)
    请问怎么样才能修改系统dll里的汇编代码而又不对系统造成破坏呢?
2011-3-20 15:57
0
雪    币: 93
活跃值: (42)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
《加密与解密》第3版18.2.4 dll劫持技术第三自然段也提到了kernel32.dll, ntdll.dll等核心系统库是不能用dll劫持技术修改的,而我期望得到的数据仅在ntdll.dll中的某个eax指向的数据,跳出ntdll.dll后就再也找不到这个数据了,我必须在ntdll.dll中加入一条call语句来实现对这个数据进行操作,请问大家该怎么办??
2011-3-21 09:39
0
雪    币: 93
活跃值: (42)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
经过几天的实验,这个确实只在ntdll.dll中出现过,跳出ntdll.dll后就再也找不到这个数据了。
请问怎么修改ntdll.dll而让它保存后有效呢?
2011-3-23 14:59
0
雪    币: 232
活跃值: (105)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
14
启动进程B
B:HOOK程序A里那个地方
让它跳转到自己的处理函数
然后结束
自己的处理函数:
..
CreateProcess(b.exe,"信息"...)
..
就可以了
吧你想要的信息当成参数传给B就是了
2011-3-23 17:06
0
雪    币: 93
活跃值: (42)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
如果我只知道程序执行到ntdll中的“mov eax,xxx”时,eax中有一个我感兴趣的数据,这个过程没有调用API,这个数据也只是在这条mov语句里出现(关键是其他地方找不到了)。
自己编程去读取这个eax里的数值,怎么才能实现呢?
2011-3-27 10:47
0
雪    币: 143
活跃值: (61)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
16
没有什么改不了的,改不了是因为你的权限不够。
其实只要有Debug权限就可以改ntdll.dll的内容了(必须改目标程序的,因为虽然每个程序都共享ntdll.dll,但是每个程序其实都有自己的...)

下面给你获得Debug权限的代码:

#ifdef X_AUTOINCLUDE
#include <Windows.h>
#else
#ifndef
_WINDOWS_
#error "XProcess的需要Windows.h支持,请 #include <Windows.h>"
#endif
#endif

#pragma
comment(lib, "kernel32.lib" )
#pragma comment(lib, "advapi32.lib" )

static BOOL SetPrivilege ( HANDLE TokenHandle, LPCTSTR PrivilegeName, BOOL EnableFlag );
BOOL SetCurrentProcessPrivilege ( LPCTSTR PrivilegeName, BOOL EnableFlag );

BOOL EnableDebug(BOOL Enable)
{
return(SetCurrentProcessPrivilege(SE_DEBUG_NAME, Enable));
}
//
//BOOL EnableCurrentProcessDebugPrivilege ( void )
//{
// return( SetCurrentProcessPrivilege( SE_DEBUG_NAME, TRUE ) );
//} /* end of EnableCurrentProcessDebugPrivilege */
//
//BOOL DisableCurrentProcessDebugPrivilege ( void )
//{
// return( SetCurrentProcessPrivilege( SE_DEBUG_NAME, FALSE ) );
//} /* end of DisableCurrentProcessDebugPrivilege */

BOOL SetCurrentProcessPrivilege ( LPCTSTR PrivilegeName, BOOL EnableFlag )
{
HANDLE TokenHandle = ( HANDLE )-1;
BOOL ret = TRUE;

/*
* Header : Declared in Winbase.h; include Windows.h.
* Library: Use Advapi32.lib.
*
* BOOL OpenProcessToken
* (
* HANDLE ProcessHandle,
* DWORD DesiredAccess,
* PHANDLE TokenHandle
* );
*/
/* */
if ( FALSE == OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &TokenHandle ) )
{
ret = FALSE;
goto SetCurrentProcessPrivilege_exit;
}
ret = SetPrivilege( TokenHandle, PrivilegeName, EnableFlag );

SetCurrentProcessPrivilege_exit:

if ( TokenHandle != ( HANDLE )-1 )
{
CloseHandle( TokenHandle );
TokenHandle = ( HANDLE )-1;
}
return( ret );
}
/* end of SetCurrentProcessPrivilege */

static BOOL SetPrivilege ( HANDLE TokenHandle, LPCTSTR PrivilegeName, BOOL EnableFlag )
{
DWORD error;
BOOL ret = TRUE;
/*
*
* typedef struct _TOKEN_PRIVILEGES
* {
* DWORD PrivilegeCount;
* LUID_AND_ATTRIBUTES Privileges[];
* } TOKEN_PRIVILEGES, *PTOKEN_PRIVILEGES;
*
* typedef struct _LUID_AND_ATTRIBUTES
* {
* LUID Luid;
* DWORD Attributes;
* } LUID_AND_ATTRIBUTES, *PLUID_AND_ATTRIBUTES;
*/
TOKEN_PRIVILEGES tp =
{
1,
{
{ {
0, 0 }, 0 }
}
};

if ( EnableFlag == TRUE )
{
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
}
/*
* BOOL LookupPrivilegeValue
* (
* LPCTSTR lpSystemName,
* LPCTSTR lpName,
* PLUID lpLuid
* );
*
* 第二形参的可取值在winnt.h中有定义,"NT Defined Privileges"
*/
if ( FALSE == LookupPrivilegeValue( NULL, PrivilegeName, &tp.Privileges[0].Luid ) )
{
ret = FALSE;
goto SetPrivilege_exit;
}
/*
* BOOL AdjustTokenPrivileges
* (
* HANDLE TokenHandle,
* BOOL DisableAllPrivileges,
* PTOKEN_PRIVILEGES NewState,
* DWORD BufferLength,
* PTOKEN_PRIVILEGES PreviousState,
* PDWORD ReturnLength
* );
*
* The AdjustTokenPrivileges function cannot add new privileges to the
* access token. It can only enable or disable the token's existing
* privileges. To determine the token's privileges, call the
* GetTokenInformation function.
*/
if ( FALSE == AdjustTokenPrivileges( TokenHandle, FALSE, &tp, sizeof( tp ), NULL, NULL ) )
{
ret = FALSE;
goto SetPrivilege_exit;
}
else
{
error = GetLastError();
/*
* 这种情况带来的误判很隐蔽,务必留心。
*
* ERROR_NOT_ALL_ASSIGNED
*/
if ( ERROR_SUCCESS != error )
{
ret = FALSE;
goto SetPrivilege_exit;
}
}

SetPrivilege_exit:

return( ret );
}
/* end of SetPrivilege */


当然,只有Debug的权限是不够的,Windows对运行代码进行了保护,所以我们还需要通过调用
DWORD dd;
VirtualProtectEx(进程ID, 你要改的地址, 要改的大小, PAGE_EXECUTE_READWRITE, &dd);

这样,我们就可以随便改了。

推荐你通过CreateRemoteThread创建一个线程,直接把Dll注入进去。
Dll入口函数那,把保护解除了(VirtualProtect,这里不需要用Ex),然后直接修改
改完就等它的好消息吧。

祝你成功^_^
2011-3-27 18:30
0
雪    币: 143
活跃值: (61)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
17
要保存的话,是要存到哪里去呢?文件中?还是传给你的exe?
如果被HOOK的程序和要那个值的程序不是同一个,我推荐用命名管道来传递值,参见MSDN的CpeateNamedPipd

当然,如果你的程序有个窗口,那么用SendMessage最省事^_^
2011-3-28 11:53
0
雪    币: 93
活跃值: (42)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
谢谢,小弟不才,麻烦给个实例
2011-3-28 21:39
0
雪    币: 93
活跃值: (42)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
是的,我也想用SendMessage来实现
我想在程序运行时,修改内存中ntdll.dll来加入SendMessage代码将这个数据传送到另一软件。
内存补丁,只需要修改内存中的数据,而不必真的去修改硬盘中的dll,可以避免修改系统dll而引起不可知的错误。
2011-3-28 22:02
0
雪    币: 143
活跃值: (61)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
20
你可以参考:
API HOOK

你把Dll里的ErrorHander,按要求改一下就可以啦^_^
你加个SendMessage给它。

大致代码:


[font=Fixedsys][color=#000080]LONG WINAPI ErrorHandler[/color][color=#0000FF](struct [/color][color=#000080]_EXCEPTION_POINTERS [/color][color=#0000FF]*[/color][color=#000080]ep[/color][color=#0000FF])
{
    [/color][/font][font=Comic Sans MS][color=#008000]// 如果SEH链已经被手动卸载了,我们就不要处理了。
    [/color][/font][font=Fixedsys][color=#0000FF]if(![/color][color=#000080]h[/color][color=#0000FF])
        return [/color][color=#FF00FF]0[/color][color=#0000FF];
        
    [/color][/font][font=Comic Sans MS][color=#008000]// 出错时的寄存器、堆栈什么的(Context),在这里,我们不能动的
    [/color][/font][font=Fixedsys][color=#000080]PCONTEXT [/color][color=#0000FF]const [/color][color=#000080]ct[/color][color=#0000FF];
    [/color][color=#000080]ct [/color][color=#0000FF]= [/color][color=#000080]ep[/color][color=#0000FF]->[/color][color=#000080]ContextRecord[/color][color=#0000FF];
    
    if([/color][color=#000080]ct[/color][color=#0000FF]->[/color][color=#000080]Eip [/color][color=#0000FF]== [/color][color=#FF0000]这里注意,要填你写入[/color][color=#000080]int3[/color][color=#FF0000]的地方[/color][color=#0000FF])
    {
        [/color][/font][font=Comic Sans MS][color=#008000]// 我们不要动它的Context
        // ct->Eip = PTR(ct->Esp, 0);
        // ct->Esp+=4;
        
        // 找到自己的窗口
        [/color][/font][font=Fixedsys][color=#000080]HWND MyWnd [/color][color=#0000FF]= [/color][color=#000080]FindWindow[/color][color=#0000FF]([/color][color=#FF00FF]0[/color][color=#0000FF], [/color][color=#FF0000]你的窗口标题[/color][color=#0000FF]);
        
        [/color][/font][font=Comic Sans MS][color=#008000]// 使用PostMessage,立即返回,以免耽误了,可能会发生什么不良影响。
        // SendMessage(MyWnd, 你定义的消息标志符, ct->Eax, 可以附加点东西);
        [/color][/font][font=Fixedsys][color=#000080]PostMessage[/color][color=#0000FF]([/color][color=#000080]MyWnd[/color][color=#0000FF], [/color][color=#FF0000]你定义的消息标志符[/color][color=#0000FF], [/color][color=#000080]ct[/color][color=#0000FF]->[/color][color=#000080]Eax[/color][color=#0000FF], [/color][color=#FF0000]可以附加点东西[/color][color=#0000FF])
        
        return -[/color][color=#FF00FF]1[/color][color=#0000FF];
    }
    
    [/color][/font][font=Comic Sans MS][color=#008000]// 不是我们要的错误,返回0让下一个SEH处理
    [/color][/font][font=Fixedsys][color=#0000FF]return [/color][color=#FF00FF]0[/color][color=#0000FF];
}
[/color][/font]



如果有什么不知道,+我QQ吧^_^
2011-3-29 13:22
0
雪    币: 47
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
15楼乃高人也!
2011-3-31 07:36
0
游客
登录 | 注册 方可回帖
返回
//