使用process_vm_readv从另一个过程中修改整数值
Modifying integer value from another process using process_vm_readv
我正在使用Ubuntu Linux编写两个程序。我试图从另一个过程中更改整数的价值。我的第一个过程(a)是一个永远循环并将值显示到屏幕的简单程序。该程序按预期运行,并简单地将值显示为屏幕的值-1430532899(0xaabbccdd)。
#include <stdio.h>
int main()
{
//The needle that I am looking for to change from another process
int x = 0xAABBCCDD;
//Loop forever printing out the value of x
int counter = 0;
while(1==1)
{
while(counter<100000000)
{
counter++;
}
counter = 0;
printf("%d",x);
fflush(stdout);
}
return 0;
}
在单独的终端中,我使用 ps -e
命令列出进程并记录进程(a)的过程ID。接下来作为root使用(sudo)我运行下一个程序(b)并输入我从过程(a)中注意到的进程ID。
该程序基本上搜索了向后内存中的针(DD CC BB AA)找到针头,并注意地址。然后,它会尝试将十六进制值(0xeeeeeee)写入同一位置,但是当将ERRNO设置为14
时,我会遇到一个错误的地址错误。奇怪的是,在地址空间中,我能够成功地将值写入地址(0x601000),但是针(0xaabbccdd)的地址在0x6005df,我无法在那里写。(但很明显,因为那是我找到针的地方)
#include <stdio.h>
#include <iostream>
#include <sys/uio.h>
#include <string>
#include <errno.h>
#include <vector>
using namespace std;
char getHex(char value);
string printHex(unsigned char* buffer, int length);
int getProcessId();
int main()
{
//Get the process ID of the process we want to read and write
int pid = getProcessId();
//Lists of addresses where we find our needle 0xAABBCCDD and the addresses where we simply cannot read
vector<long> needleAddresses;
vector<long> unableToReadAddresses;
unsigned char buf1[1000]; //buffer used to store memory values read from other process
//Number of bytes read, also is -1 if an error has occurred
ssize_t nread;
//Structures used in the process_vm_readv system call
struct iovec local[1];
struct iovec remote[1];
local[0].iov_base = buf1;
local[0].iov_len = 1000;
remote[0].iov_base = (void * ) 0x00000; //start at address 0 and work up
remote[0].iov_len = 1000;
for(int i=0;i<10000;i++)
{
nread = process_vm_readv(pid, local, 1, remote, 1 ,0);
if(nread == -1)
{
//errno is 14 then the problem is "bad address"
if(errno == 14)
unableToReadAddresses.push_back((long)remote[0].iov_base);
}
else
{
cout<<printHex(buf1,local[0].iov_len);
for(int j=0;j<1000-3;j++)
{
if(buf1[j] == 0xDD && buf1[j+1] == 0xCC && buf1[j+2] == 0xBB && buf1[j+3] == 0xAA)
{
needleAddresses.push_back((long)(remote[0].iov_base+j));
}
}
}
remote[0].iov_base += 1000;
}
cout<<"Addresses found at...";
for(int i=0;i<needleAddresses.size();i++)
{
cout<<needleAddresses[i]<<endl;
}
//How many bytes written
int nwrite = 0;
struct iovec local2[1];
struct iovec remote2[1];
unsigned char data[] = {0xEE,0xEE,0xEE,0xEE};
local2[0].iov_base = data;
local2[0].iov_len = 4;
remote2[0].iov_base = (void*)0x601000;
remote2[0].iov_len = 4;
for(int i=0;i<needleAddresses.size();i++)
{
cout<<"Attempting to write "<<printHex(data,4)<<" to address "<<needleAddresses[i]<<endl;
remote2[0].iov_base = (void*)needleAddresses[i];
nwrite = process_vm_writev(pid,local2,1,remote2,1,0);
if(nwrite == -1)
{
cout<<"Error writing to "<<needleAddresses[i]<<endl;
}
else
{
cout<<"Successfully wrote data";
}
}
//For some reason THIS will work
remote2[0].iov_base = (void*)0x601000;
nwrite = process_vm_writev(pid,local2,1,remote2,1,0);
cout<<"Wrote "<<nwrite<<" Bytes to the address "<<0x601000 <<" "<<errno;
return 0;
}
string printHex(unsigned char* buffer, int length)
{
string retval;
char temp;
for(int i=0;i<length;i++)
{
temp = buffer[i];
temp = temp>>4;
temp = temp & 0x0F;
retval += getHex(temp);
temp = buffer[i];
temp = temp & 0x0F;
retval += getHex(temp);
retval += ' ';
}
return retval;
}
char getHex(char value)
{
if(value < 10)
{
return value+'0';
}
else
{
value = value - 10;
return value+'A';
}
}
int getProcessId()
{
int data = 0;
printf("Please enter the process id...");
scanf("%d",&data);
return data;
}
底线是我无法修改另一个过程重复打印的整数。
我至少可以看到这些问题。
-
没有人保证该过程的可写入内存中的任何地方都有0xaabbccdd。编译器可以将其完全优化或放入寄存器中。ensure的一种方法将在主内存中放置一个变量是将其声明为
volatile
。volatile int x = 0xAABBCCDDEE;
-
没有人保证有 no 0xaabbccdd在 read-nolly 内存中的某个地方。相反,可以很确定那里确实存在这样的价值。该程序还可以在哪里获取它来初始化变量?初始化可能转化为类似于此
的汇编指令mov eax, 0xAABBCCDD
毫不奇怪,它包含与0xaabbccdd匹配的位模式。地址0x6005DF很可能在.TEXT部分中。它不太可能在堆栈上,因为堆栈地址通常靠近地址空间的顶部。
-
64位过程的地址空间很大。没有希望在合理的时间内遍历这一切。一个人需要以某种方式限制地址的范围。
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 是否删除在对象构造过程中创建的对象
- 如何在鼠标挂钩过程中检测拖动
- clang 插件:在编译过程中修改 AST
- 在 RAII 构造中修改 RVO 值是否安全?
- 在 C++ 中修改 Grpc 双向流式处理期间的元数据
- 当使用我在一个函数、另一个函数中修改的数组时,在我的输出中得到一个奇怪的负数
- Adafruit 羽毛RFM69HCW在使用过程中会冻结,需要硬重置
- 线程过程中的线程同步问题
- MySQL 连接器/C++.尝试在此过程中停止连接到数据库
- C++ 在编译过程中 strtok 函数 Eclipse 说没有在范围内声明?
- 在调用过程中删除 std::函数
- 动态矩阵特征分解过程中的误差
- cmake在构建过程中使用另一个工具检测标志
- 在模板参数推导过程中丢失限定符
- 升压过程中的管道缓冲区大小
- 如何在插入过程中更改插入的值
- 使用process_vm_readv从另一个过程中修改整数值
- 通过构造过程中获得的指针修改const对象
- 通过引用,源在操作过程中被修改