最近写的一些好玩的code小片段,与君共享

threeleafzerg007 2014-01-17 02:36:21

#include <stdlib.h>
#include <stdio.h>
#include <sys/mman.h>
#include <string.h>

#define PAGESIZE 4096

int main(int argc, char *argv[])
{
void *p1 = &&L1;
unsigned char *buf = calloc(sizeof(unsigned char),30);
void *aligned_addr = (char*)(((unsigned long)buf) & ~(PAGESIZE - 1));
int errno = mprotect(aligned_addr, PAGESIZE, PROT_WRITE | PROT_READ | PROT_EXEC);
if(errno != 0) {
printf("error %d:%s\n",errno,strerror(errno));
return errno;
}

unsigned int offset = (unsigned int)((unsigned long)p1 - (unsigned long)buf - 5);

buf[0] = '\xe9';
buf[1] = (unsigned char)(offset & 0xFF);
buf[2] = (unsigned char)(offset >> 8 & 0xFF);
buf[3] = (unsigned char)(offset >> 16 & 0xFF);
buf[4] = (unsigned char)(offset >> 24 & 0xFF);

asm volatile(
"jmp *%0\n\t"
:
:"r"((void *)buf)
);
goto L1;
return 0;
L1:
printf("hit L1,congratulation!\n");
return 0;
}


...全文
634 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
threeleafzerg007 2014-01-21
  • 打赏
  • 举报
回复
散分,所有动手写码的都给高分,纯粹接分的,一分不给!
zhh157 2014-01-19
  • 打赏
  • 举报
回复
引用 25 楼 huoqingna2332 的回复:
[quote=引用 4 楼 zhao4zhong1 的回复:] 对学习编程者的忠告: 眼过千遍不如手过一遍! 书看千行不如手敲一行! 手敲千行不如单步一行! 单步源代码千行不如单步对应汇编一行!
见识了![/quote] 单步对应汇编一行,不如单步对应汇编两行。 接分!!!
零度的折翅 2014-01-19
  • 打赏
  • 举报
回复
引用 4 楼 zhao4zhong1 的回复:
对学习编程者的忠告: 眼过千遍不如手过一遍! 书看千行不如手敲一行! 手敲千行不如单步一行! 单步源代码千行不如单步对应汇编一行!
见识了!
DuanKong86 2014-01-19
  • 打赏
  • 举报
回复
应该是hot hook的节奏
cheney1227 2014-01-19
  • 打赏
  • 举报
回复
学习了!~~~~~
erick08 2014-01-19
  • 打赏
  • 举报
回复
JiMoKuangXiangQu 2014-01-18
  • 打赏
  • 举报
回复
ram code,呵呵。
会笑的苦瓜 2014-01-18
  • 打赏
  • 举报
回复
谢谢19#为我垫底。
lwouyang 2014-01-18
  • 打赏
  • 举报
回复
无聊过来看看。哈哈,有发现。一向深居简出的标号,一出场就万分瞩目。谢谢 LZ 展示了标号的又一种用法,尽管只是 GCC 下的。GCC 深不可测啊! 查了下 0xE9 是 x86 短跳转指令 opcode,容易猜测到放到 buf 里的指令是用来跳到 L1 的。 代码不够简洁啊,不知道是LZ太过小心了还是有意做的,核心代码都给一大堆类型转换淹没掉了。做了点小修改简化一下。冒犯莫怪!^_^ 由于缺少系统库文件,代码没有经测试。慎用!
#include <stdlib.h>
#include <stdio.h>
#include <sys/mman.h>

#define PAGESIZE 4096

int main(int argc, char *argv[])
{
    char* buf = (char*)malloc(30);
    void* page_addr = (void*)(((unsigned long)buf) & ~(PAGESIZE - 1));
    int errno = mprotect(page_addr, PAGESIZE, PROT_WRITE | PROT_READ | PROT_EXEC);
    if(errno != 0) {
        printf("error %d:%s\n",errno,strerror(errno));
        return errno;
    }
    void* p1 = &&L1;
    unsigned long offset = (char*)p1 - buf - 5;

    *buf++ = '\xe9';
    *(unsigned long*)buf-- = offset;

    asm volatile("jmp *%0\n\t"::"r"(buf));
    printf("Tricky code. Right?\n");
L1:
    printf("Hit L1. Congratulation!\n");
    return 0;
}
另外,LZ说的那个goto L1;去掉的话,看了下对应汇编码,后面的代码的不见了,估计GCC认为return 0;后面的代码没用直接拿掉了吧,甚至于连printf都被直接换成了puts,字符串后的'\n'也被拿掉了。即使用-O0也没用。再次表示GCC水深啊,谨慎!
纹枰老妖 2014-01-17
  • 打赏
  • 举报
回复
谢谢19#为我垫底。
lzjamao 2014-01-17
  • 打赏
  • 举报
回复
代码是干神马的!
ztenv 版主 2014-01-17
  • 打赏
  • 举报
回复
没有什么,很简单的而已
「已注销」 2014-01-17
  • 打赏
  • 举报
回复
#include <stdio.h>

void test()
{
    printf("------> I'm the test function!!! <-------\n");
}

int main(int argc, char *argv[])
{
    unsigned char *buf = new unsigned char[5]; 

    buf[0] = '\xe9';
    *(unsigned int*)(buf+1) = (unsigned int)((unsigned long)test - (unsigned long)buf - 5);
    
    __asm 
    {
        lea eax, L1
        push eax
        jmp buf 
    }
    return 0;
    
L1:
    printf("hit L1,congratulation!\n");
    return 0;
}
  • 打赏
  • 举报
回复
引用 12 楼 laq616853363 的回复:
[quote=引用 4 楼 zhao4zhong1 的回复:] 对学习编程者的忠告: 眼过千遍不如手过一遍! 书看千行不如手敲一行! 手敲千行不如单步一行! 单步源代码千行不如单步对应汇编一行!
受教了~[/quote]我觉得最后一步太可怕
寒沙胜雪 2014-01-17
  • 打赏
  • 举报
回复
不 明 觉 厉
漫步者、 2014-01-17
  • 打赏
  • 举报
回复
分享的是干啥的
Csharp_琪 2014-01-17
  • 打赏
  • 举报
回复
引用 4 楼 zhao4zhong1 的回复:
对学习编程者的忠告: 眼过千遍不如手过一遍! 书看千行不如手敲一行! 手敲千行不如单步一行! 单步源代码千行不如单步对应汇编一行!
受教了~
「已注销」 2014-01-17
  • 打赏
  • 举报
回复
如果发现楼上代码编译不通过,那修改 errno 变量名即可,在vs08中发现 errno 变量是编译器内置的,无法使用。 lz这是要做 inline hook 的节奏吗?
starytx 2014-01-17
  • 打赏
  • 举报
回复
不明觉厉
「已注销」 2014-01-17
  • 打赏
  • 举报
回复
无聊的过来把它改成windows版本的
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
#include <string.h>

#define PAGESIZE 4096

int main(int argc, char *argv[])
{
    void *p1;
    DWORD OldProtect;
    unsigned char *buf = (unsigned char*)calloc(sizeof(unsigned char), 30);
    void *aligned_addr = (char*)(((unsigned long)buf) & ~(PAGESIZE - 1));
    int errno = VirtualProtect(aligned_addr, PAGESIZE, PAGE_EXECUTE_READWRITE, &OldProtect);
    if(errno != TRUE) {
        printf("error %d:%s\n",errno,strerror(errno));
        return errno;
    }
    
    __asm 
    {
        lea eax, L1
        mov p1, eax
    }
    unsigned int offset = (unsigned int)((unsigned long)p1 - (unsigned long)buf - 5);
    
    buf[0] = '\xe9';
    buf[1] = (unsigned char)(offset & 0xFF);
    buf[2] = (unsigned char)(offset >> 8 & 0xFF);
    buf[3] = (unsigned char)(offset >> 16 & 0xFF);
    buf[4] = (unsigned char)(offset >> 24 & 0xFF);
    
    __asm 
    {
        mov eax,buf
        jmp eax
    }
    return 0;

L1:
    printf("hit L1,congratulation!\n");
    return 0;
}
加载更多回复(8)

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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