我试图模仿Cheat Engine在Mac OS上从值中获取内存地址并修改它的做法。到目前为止,我已经做到了:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <libproc.h>
#include <mach/mach_init.h>
// Get array of all process ids
uint32_t* get_pids(uint16_t* size) {
uint32_t number_of_pids = proc_listpids(1, 0, NULL, 0);
uint32_t* buffer = malloc(sizeof(uint32_t) * number_of_pids);
uint8_t return_code = proc_listpids(1, 0, buffer, sizeof(buffer) * number_of_pids);
uint16_t sum = 0;
for(int i = 0; i < number_of_pids; i++) {
if(buffer[i] != 0) {
sum++;
}
}
uint32_t* final = malloc(sizeof(uint32_t) * sum);
for(int i = 0, t = 0; i < number_of_pids; i++) {
if(buffer[i]) {
final[t++] = buffer[i];
}
}
*size = sum;
return final;
}
int main() {
uint16_t size;
uint32_t* pids = get_pids(&size);
uint16_t maxpathlength = 1024;
uint16_t path_size = maxpathlength * 4;
char path_buffer[path_size];
uint32_t pid = 0;
for(int i = 0; i < size; i++) {
memset(path_buffer, '\0', sizeof(path_buffer));
uint8_t return_code = proc_pidpath(pids[i], path_buffer, path_size);
if(strstr(path_buffer, "Geometry Dash")) {
pid = pids[i];
}
//printf("PID: %d, Process: %s\n", pids[i], path_buffer);
}
mach_port_name_t port = 0;
if(task_for_pid(mach_task_self(), pid, &port)) {
printf("Run as root!\n");
}
printf("%d\n", port);
return 0;
}
所以我到了那里,现在有目标pid的mach端口,但是我不知道从这里去哪里,因为我发现几乎0关于mach_vm
方法的好文档,我尝试的任何东西都失败了。我应该如何去做呢?
1条答案
按热度按时间yacmzcpb1#
所以我找到了如何做到这一点,这是非常简单的,但同样几乎没有任何文档,要读取进程内存,你有这样的:
很明显,
task
是目标pid的端口,您可以通过简单的命令获得:但是你必须运行
sudo
才能正常工作。data
是读取内存将要进入的缓冲区,dataCnt
是输入时读取内存的最大大小和输出时读取的实际内存大小。你还必须根据虚拟内存的数据类型进行适当的强制转换才能正确读取它。因此对于字符串,你必须将上述函数的返回值强制转换为char *
,但是对于整数,它将是int *
。将内存写入进程几乎是相同的:
但是这次
dataCnt
是将要写入的输入的字节,而data
保存您想要写入到目标进程虚拟存储器地址的字节。示例:
从python进程内存读写字符串(48是python3中变量内存地址的实际字符串偏移量):
以及
以及
而24是偏移量,以从变量地址获得Python存储器中的实际整数。