Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
247 views
in Technique[技术] by (71.8m points)

c - 在Linux中如何从内存中读取和更改值?(How to read and change value from memory in Linux?)

The code inside main.c

(main.c中的代码)

#include <stdio.h>
#include <unistd.h>

int main() {
    int c_variable = 0; // the target

    for(int x = 0; x < 100; x++) {
        c_variable += 5; // increase by 5 to change the value of the int
        printf("%i
", c_variable); // print current value
        sleep(8); // sleep so I have time to scan memory
    }

    return 0;

}

What I am trying to achieve is to read the integer c_variable and then to modify it inside another .c program.

(我想要实现的是读取整数c_variable ,然后在另一个.c程序中对其进行修改。)

I am on linux so I did ps -A | grep main

(我在linux上,所以我做了ps -A | grep main)

ps -A | grep main and got the PID of the running program.

(ps -A | grep main并获取正在运行的程序的PID。)

I then did sudo scanmem PID and entered the current value of c_variable a few times.

(然后,我做了sudo scanmem PID并输入了c_variable的当前值几次。)

I was left with three memory addresses and executing the command set 500 changed the value the program printed, effectively changing the memory address' value to 500 instead of 35 or whatever the program was currently at.

(我只有三个内存地址,执行命令set 500更改程序打印的值,有效地将内存地址的值更改为500,而不是35或程序当前所在的位置。)

I then executed the following code

(然后我执行了以下代码)

#include <stdio.h>

int main() {
    const long unsigned addr = 0x772d85fa1008; // one of the three addresses from scanmem
    printf("%lu
", addr);

    return 0;
}

but I got some random long string of numbers, not the current number.

(但是我得到了一些随机的长字符串,而不是当前数字。)

The tutorials and answers I have read on how to read and write memory on linux does not have to use long unsigned but can use char* or just int* instead.

(我已经阅读了有关如何在linux上读写内存的教程和答案,不必使用long unsigned而可以使用char *或int *。)

My memory address seems to be a bit long, I have not see memory addresses that long before.

(我的内存地址似乎有点长,不久之前我还没有看到内存地址。)

Anyhow, how do I read and write the memory address of the integer c_variable ?

(无论如何,我如何读写整数c_variable的内存地址?)

Edit: the output of scanmem looks something like this

(编辑:scanmem的输出看起来像这样)

info: we currently have 3 matches.
3> list
[ 0] 7771ff64b090,  6 +        1e090, stack, 20, [I64 I32 I16 I8 ]
[ 1] 7771ff64b5d8,  6 +        1e5d8, stack, 20, [I64 I32 I16 I8 ]
[ 2] 7771ff64b698,  6 +        1e698, stack, 20, [I32 I16 I8 ]
3> set 50
info: setting *0x7771ff64b090 to 0x32...
info: setting *0x7771ff64b5d8 to 0x32...
info: setting *0x7771ff64b698 to 0x32...

output

(输出)

...
150
155
160
165
170
175
55
60
65
...
  ask by RealAnwersOnly translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You're printing the actual address number, but in in decimal notation, not what is at the address.

(您正在打印实际的地址号,但以十进制表示,而不是地址的数字。)

const int *addr = (int *) 0x772d85fa1008;
printf("%d
", *addr);

You have to declare addr as a pointer type.

(您必须将addr声明为指针类型。)

More specifically a pointer to an integer .

(更具体地说,是指向整数的指针。)

Its value ( 0x772d85fa1008 ) holds the address of the integer.

(其值( 0x772d85fa1008 )保存该整数的地址 。)

Then, in the printf call you dereference it to obtain the actual integer stored at the address.

(然后,在printf调用中取消引用它以获得存储在地址中的实际整数。)

Although in practice I can't vouch for whether this is going to work, since memory in modern operating systems isn't as simple as you make it out to be.

(尽管实际上我不能保证这是否会奏效,因为现代操作系统中的内存并不像您想象的那么简单。)

But I don't have enough knowledge to assess that.

(但是我没有足够的知识来评估这一点。)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...