自修改代码在高级优化下不起作用
我尝试编写一个自修改代码。 (请参阅链接 https://shanetully。 com/2013/12/writing-a-self-mutating-x86_64-c-program/)自修改代码在没有优化的情况下有效(-o0)
gcc -O0 smc.c -o smc
Calling foo...
i: 1
Calling foo...
i: 42
而当优化级别增加时 (-O1-O2-O3..) 自修改代码不再起作用。
gcc -O3 smc.c -o smc
Calling foo...
i: 1
Calling foo...
i: 1
是否可以使自修改代码与 -O3 级别优化一起工作,我应该做什么?
程序如下:
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/mman.h>
void foo(void);
int change_page_permissions_of_address(void *addr);
int main(void) {
void *foo_addr = (void*)foo;
// Change the permissions of the page that contains foo() to read, write, and execute
// This assumes that foo() is fully contained by a single page
if(change_page_permissions_of_address(foo_addr) == -1) {
fprintf(stderr, "Error while changing page permissions of foo(): %s\n", strerror(errno));
return 1;
}
// Call the unmodified foo()
puts("Calling foo...");
foo();
// Change the immediate value in the addl instruction in foo() to 42
unsigned char *instruction = (unsigned char*)foo_addr + 22;
// Notice that 22 here is the offset that I compiled. Different compilations and machine offsets may vary.
*instruction = 0x2A;
// Call the modified foo()
puts("Calling foo...");
foo();
return 0;
}
void foo(void) {
int i=0;
i++;
printf("i: %d\n", i);
}
int change_page_permissions_of_address(void *addr) {
// Move the pointer to the page boundary
int page_size = getpagesize();
addr -= (unsigned long)addr % page_size;
if(mprotect(addr, page_size, PROT_READ | PROT_WRITE | PROT_EXEC) == -1)
{
return -1;
}
return 0;
}
I tried to write a self-modifying code. (Refer to the link https://shanetully.com/2013/12/writing-a-self-mutating-x86_64-c-program/) The self-modifying code works when there is no optimization (-o0)
gcc -O0 smc.c -o smc
Calling foo...
i: 1
Calling foo...
i: 42
while when the optimization level increases (-O1-O2-O3..) Self-modifying code no longer works.
gcc -O3 smc.c -o smc
Calling foo...
i: 1
Calling foo...
i: 1
Is it possible to make self-modifying code work with -O3 level optimization, and what should I do?
The program is as follows:
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/mman.h>
void foo(void);
int change_page_permissions_of_address(void *addr);
int main(void) {
void *foo_addr = (void*)foo;
// Change the permissions of the page that contains foo() to read, write, and execute
// This assumes that foo() is fully contained by a single page
if(change_page_permissions_of_address(foo_addr) == -1) {
fprintf(stderr, "Error while changing page permissions of foo(): %s\n", strerror(errno));
return 1;
}
// Call the unmodified foo()
puts("Calling foo...");
foo();
// Change the immediate value in the addl instruction in foo() to 42
unsigned char *instruction = (unsigned char*)foo_addr + 22;
// Notice that 22 here is the offset that I compiled. Different compilations and machine offsets may vary.
*instruction = 0x2A;
// Call the modified foo()
puts("Calling foo...");
foo();
return 0;
}
void foo(void) {
int i=0;
i++;
printf("i: %d\n", i);
}
int change_page_permissions_of_address(void *addr) {
// Move the pointer to the page boundary
int page_size = getpagesize();
addr -= (unsigned long)addr % page_size;
if(mprotect(addr, page_size, PROT_READ | PROT_WRITE | PROT_EXEC) == -1)
{
return -1;
}
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论