(大神留步)问个比较难的问题,关于内核中内存的..~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

yxwsbobo 2011-07-05 07:42:32
最近写个小程序,需要保存一些简单信息,但是又不想用注册表和另外的文件,所以想在程序运行中修改自身EXE,在R3层实现

进程句柄好像有个访问掩码,有点映象,但看书不够仔细记不清了,,希望大牛给指点一下,有什么好方法实现修改自身EXE


进入主题了,EXE在内存中是分页的,也就是说系统有可能把程序内存中最近不使用的置换到物理文件中,当使用内存的时候,再将物理文件中的内容置换到内存中,运行中的EXE在内存中是以内存映射文件存在的,也就是说他的物理文件就是 EXE,但是现在EXE又被修改了,那么他会将以修改的EXE再次修改回来吗?如果不修改,那当访问内存而将物理文件中的内容读取到内存中时会出错吧?他自己也不知道EXE已经被修改了,所以应该不会将内存中的数据存储到其他文件中吧
...全文
350 43 打赏 收藏 转发到动态 举报
写回复
用AI写文章
43 条回复
切换为时间正序
请发表友善的回复…
发表回复
Lactoferrin 2011-08-10
  • 打赏
  • 举报
回复
NtSystemDebugControl 在xp中有读取和设置内核空间的内存的功能,但在windows7没有
yxwsbobo 2011-08-10
  • 打赏
  • 举报
回复
跟了一下NtSystemDebugControl 在WIN7中只实现了个别几个服务功能 但在XP中好像都实现了哦 我只跟了ReadVirtual 和 WriteVirtual 是没有问题的 可以读取和设置 内核空间的内存

XP SP3
yxwsbobo 2011-08-09
  • 打赏
  • 举报
回复
结贴了 以后如果找到完美办法就来说一下
yxwsbobo 2011-08-09
  • 打赏
  • 举报
回复
好的 谢谢



Lactoferrin 2011-08-09
  • 打赏
  • 举报
回复
原理就是ntfs文件记录包含一堆属性,数据属性描述文件的数据流,a.exe:settings表示是a.exe的一个叫settings 的数据属性
yxwsbobo 2011-08-09
  • 打赏
  • 举报
回复
在网吧 不能测试 讲解下原理呗 是异步参数 还是 settings
Lactoferrin 2011-08-09
  • 打赏
  • 举报
回复
HANDLE h=CreateFile("D:\\Project\\ConsoleTest\\Release\\a.exe:settings",FILE_READ_DATA|FILE_WRITE_DATA|SYNCHRONIZE,1,0,OPEN_ALWAYS,0x80,0);
cout<<hex;
cout<<h<<endl;DWORD c;char Buffer[32];
cout<<WriteFile(h,"123123",5,&c,0)<<endl;
SetFilePointer(h,0,0,0);
cout<<ReadFile(h,Buffer,5,&c,0)<<endl;
cout<<Buffer<<endl;
a.exe在运行时也可修改
yxwsbobo 2011-08-09
  • 打赏
  • 举报
回复
跟踪看了一下 NtQuery* 一堆函数 都是只能查询 不能修改 或不能修改重要信息 看了一下其他函数也没有跳过的方法


命名数据流来是什么呢?
yxwsbobo 2011-08-09
  • 打赏
  • 举报
回复
哈哈, 就是这2个方法 只记得大概,看到了就认识了


那个文章里还有2个方法 不过说不定也一样被封了

以后再找找把,问题就是想办法修改内核空间代码了

不管怎么说 你的方法是最好的了

Lactoferrin 2011-08-09
  • 打赏
  • 举报
回复
如果你能保证exe都在ntfs文件系统上可以使用命名数据流来保存其他信息
Lactoferrin 2011-08-09
  • 打赏
  • 举报
回复
windows xp下用的NtSystemDebugControl的读写内核空间的功能和ZwOpenSection打开\Device\PhysicalMemory在windows server 2003 sp1就被封了

后面windbg读写内核空间也是用的驱动程序
yxwsbobo 2011-08-09
  • 打赏
  • 举报
回复
呵呵,是需要修改系统空间,不过只是修改下内存也可以不用驱动,在网吧函数没记住 WINDBG用的本地内核调试 就是通过一组非文档 内核调试API实现的 可以直接读取修改和其他操作内核内存,XP下可以直接使用 VISTA 需要 bcdedit /debug on 开启调试

还有看过一片文章也是可以修改内核空间内存的,大概意思就是直接获得物理内存设备,然后修改
Lactoferrin 2011-08-09
  • 打赏
  • 举报
回复
你已经用了驱动程序了,这就没意思了,修改内存页保护属性是没有用的
yxwsbobo 2011-08-09
  • 打赏
  • 举报
回复
一直没的网上 真悲剧


解决了,原理是首先CreateFile 以只读方式打开目标文件,这样就获得了一个句柄,只是没有写权限,权限保存在句柄表 对应ENTRY 的 HANDLE_TABLE_ENTRY 其中的 GrantedAccess 就是了 修改成-1就有了所有权限了



不明白那么多人为什么要修改内存页保护属性。。。
sunlin7 2011-07-27
  • 打赏
  • 举报
回复
最简单稳定有效且可移植性好的办法是使用一个临时可执行文件,修改这个文件,然后这个临时的可执行文件自删除就可以了.
csx007700 2011-07-25
  • 打赏
  • 举报
回复
write paging io 刚打错了
csx007700 2011-07-25
  • 打赏
  • 举报
回复
如果lz要保存到硬盘上的话可以想办法发送一个pageing io写请求 用DeviceIoContrl应该可以的
csx007700 2011-07-25
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 yxwsbobo 的回复:]
驱动当然无所不能了,我现在想走无驱动的路子


to #7 有参考代码吗,零碎的部分也行


to #8 OD打补丁可以在程序中运行修改EXE吗 我OD用的不是很多 记忆中OD打补丁会生成新的文件保存
[/Quote]


#include "windows.h"

//
//获取EIP地址内容
//
__declspec(naked) void * GetCurrentEIP()
{
__asm{
pop eax
push eax
ret
}
}

//
//修改页面属性 这里lz应该没问题吧 就不注释了
//
void SetPageWriteable()
{
DWORD MaxAddr;
DWORD CurAddr;
DWORD PageSize;
DWORD OldProtect;

HANDLE hProc;

SYSTEM_INFO SysInfo;
MEMORY_BASIC_INFORMATION MemBasicInfo;

GetSystemInfo(&SysInfo);
MaxAddr =(DWORD)SysInfo.lpMaximumApplicationAddress;
PageSize = SysInfo.dwPageSize;
hProc =GetCurrentProcess();

for(CurAddr =(DWORD)SysInfo.lpMinimumApplicationAddress; CurAddr <= MaxAddr; CurAddr += PageSize)
{

if(VirtualQueryEx(hProc, (LPVOID)(CurAddr), &MemBasicInfo, sizeof(MEMORY_BASIC_INFORMATION)))
{
VirtualProtectEx(hProc, MemBasicInfo.BaseAddress, MemBasicInfo.RegionSize, PAGE_EXECUTE_READWRITE, &OldProtect);
CurAddr += MemBasicInfo.RegionSize;
}
}


CloseHandle(hProc);
return;
}

int _tmain(int argc, _TCHAR* argv[])
{
char * EIP;

char Signature[] = {0xB8,0x01,0x00,0x00,0x00,0x85,0xC0,0x74,0x19};

SetPageWriteable();

//
//获取EIP后往后看 if跳转反汇编是这样的
// B8 01 00 00 00 mov eax,1
// 85 C0 test eax,eax
// 74 19 je wmain+48h (411448h)
//
//我们把另外把B8 01 00 00 00 85 C0 74 19作为特征码
//找到je (0x74)改成jne(0x75)
//

EIP = (char *)GetCurrentEIP();

//
//查找
//
while(memcmp(Signature,EIP,sizeof(Signature)))
{
EIP++;
}

//
//找到了 把它改了 先定位到0x74
//
EIP += 7;

*EIP = 0x75;

if(1)
{
printf("Should come here!\n");
}
else
{
printf("Oh ,Code has been changed!\n");
}

return 0;
}


做了个改跳转的例子 lz看看吧
「已注销」 2011-07-20
  • 打赏
  • 举报
回复
直接打开硬盘读写,这样系统就管不到了~~~不过这个硬盘结构我可没研究……

HANDLE hFile=CreateFile( //打开硬盘
"\\\\.\\PHYSICALDRIVE0",
GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE,
0,
OPEN_EXISTING,
0,
0);
jamseyang 2011-07-20
  • 打赏
  • 举报
回复
非大神路过学习下。。。
加载更多回复(23)
主要特性Java 语言是简单的:Java 语言的语法与 C 语言和 C++ 语言很接近,使得大多数程序员很容易学习和使用。另一方面,Java 丢弃了 C++ 很少使用的、很理解的、令人迷惑的那些特性,如操作符重载、多继承、自动的强制类型转换。特别地,Java 语言不使用指针,而是引用。并提供了自动分配和回收内存空间,使得程序员不必为内存管理而担忧。Java 语言是面向对象的:Java 语言提供类、接口和继承等面向对象的特性,为了简单起见,只支持类之间的单继承,但支持接口之间的多继承,并支持类与接口之间的实现机制(关键字为 implements)。Java 语言全面支持动态绑定,而 C++语言只对虚函数使用动态绑定。总之,Java语言是一个纯的面向对象程序设计语言。Java语言是分布式的:Java 语言支持 Internet 应用的开发,在基本的 Java 应用编程接口有一个网络应用编程接口(java net),它提供了用于网络应用编程的类库,包括 URL、URLConnection、Socket、ServerSocket 等。Java 的 RMI(远程方法激活)机制也是开发分布式应用的重要手段。Java 语言是健壮的:Java 的强类型机制、异常处理、垃圾的自动收集等是 Java 程序健壮性的重要保证。对指针的丢弃是 Java 的明智选择。Java 的安全检查机制使得 Java 更具健壮性。Java语言是安全的:Java通常被用在网络环境,为此,Java 提供了一个安全机制以防恶意代码的攻击。除了Java 语言具有的许多安全特性以外,Java 对通过网络下载的类具有一个安全防范机制(类 ClassLoader),如分配不同的名字空间以防替代本地的同名类、字节代码检查,并提供安全管理机制(类 SecurityManager)让 Java 应用设置安全哨兵。Java 语言是体系结构立的:Java 程序(后缀为 java 的文件)在 Java 平台上被编译为体系结构立的字节码格式(后缀为 class 的文件),然后可以在实现这个 Java 平台的任何系统运行。这种途径适合于异构的网络环境和软件的分发。Java 语言是可移植的:这种可移植性来源于体系结构立性,另外,Java 还严格规定了各个基本数据类型的长度。Java 系统本身也具有很强的可移植性,Java 编译器是用 Java 实现的,Java 的运行环境是用 ANSI C 实现的。Java 语言是解释型的:如前所述,Java 程序在 Java 平台上被编译为字节码格式,然后可以在实现这个 Java 平台的任何系统运行。在运行时,Java 平台的 Java 解释器对这些字节码进行解释执行,执行过程需要的类在联接阶段被载入到运行环境。Java 是高性能的:与那些解释型的高级脚本语言相比,Java 的确是高性能的。事实上,Java 的运行速度随着 JIT(Just-In-Time)编译器技术的发展越来越接近于 C++。Java 语言是多线程的:在 Java 语言,线程是一种特殊的对象,它必须由 Thread 类或其子(孙)类来创建。通常有两种方法来创建线程:其一,使用型构为 Thread(Runnable) 的构造子类将一个实现了 Runnable 接口的对象包装成一个线程,其二,从 Thread 类派生出子类并重写 run 方法,使用该子类创建的对象即为线程。值得注意的是 Thread 类已经实现了 Runnable 接口,因此,任何一个线程均有它的 run 方法,而 run 方法包含了线程所要运行的代码。线程的活动由一组方法来控制。Java 语言支持多个线程的同时执行,并提供多线程之间的同步机制(关键字为 synchronized)。Java 语言是动态的:Java 语言的设计目标之一是适应于动态变化的环境。Java 程序需要的类能够动态地被载入到运行环境,也可以通过网络来载入所需要的类。这也有利于软件的升级。另外,Java 的类有一个运行时刻的表示,能进行运行时刻的类型检查。

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧