仅是个示例代码,今天上午写代码突然发现堆栈可以在高级语言中通过函数参数指针修改,
所以丢了这个东西出来.如有雷同,纯属巧合,也请你告诉我,让我学习;)

好处是,编译后没有jmp指令,通过ret 跳转到需要的代码,另外在调试时,某些代码会被当作数据,可以增加调试难度.
缺点,需要调用函数的堆栈有至少4个字节的空间,否则堆栈返回出错.
但是这四个字节空间不会被摧毁.
可能我有些东西还没有照顾到,如果有错误,大家告诉我;)

编译环境: vc6 vc7
原来的代码在编译器优化的情况下无法跳回调用函数,改了下;)

代码:

#include <stdio.h>

int  somefunc( void *ptr)
{
    printf("in somefunc...\n");
    return 0;
}

void stackbuild( void *ptr)
{
    printf("in stackbuild...\n");
    *(unsigned int*)(&ptr-1) ^= *(unsigned int*) &ptr;
    *(unsigned int*)&ptr ^= *(unsigned int*) (&ptr-1);  //注意此处对堆栈操作
    *(unsigned int*)(&ptr-1) ^= *(unsigned int*) &ptr;
}

int main(int argc, char *argv[])
{
    // 还是嵌入了一句汇编,平衡堆栈;)哪位高人改改,看能不能把嵌入汇编去掉
    __asm{push 0} //预留4字节空间,平衡堆栈,注意此句和下面的句子要一起用,没有下面的调用,必须没有该语句
    stackbuild(somefunc);

    printf("exit main...\n");
    return 0;
}

  • 标 题:答复
  • 作 者:foxabu
  • 时 间:2007-08-23 00:49

#include "stdafx.h"
#include <stdio.h>
#include "stdlib.h"
int somefunc( void *ptr)
{
    printf("in somefunc...\n");
    return 0;
}

void _declspec(naked) __cdecl stackbuild(void *ptr)
{
  __asm
  {
    push ebp
    mov ebp,esp
    sub esp, __LOCAL_SIZE
  }
    printf("in stackbuild...\n");
  __asm
  {
    mov esp,ebp
      pop ebp
    push [esp+4]
    ret
  }
  
}

int main(int argc, char *argv[])
{

    stackbuild(somefunc);

    printf("exit main...\n");
  system("PAUSE");
    return 0;
}

DEBUG Or Release Tested. VC++ 8sp1

  • 标 题:答复
  • 作 者:softdiy
  • 时 间:2007-08-23 09:12

那这样也可以了,因为naked不可以初始化数据的,所以退出时,esp总是指向同一个位置

文章本意是使用传进去的指针操纵栈区的,但是还是要加了一个push在外面,看来此路不通

代码:

#include <stdio.h>
int somefunc( void *ptr)
{
    printf("in somefunc...\n");
    return 0;
}

void _declspec(naked) __cdecl stackbuild(void *ptr1)
{
    printf("in stackbuild...\n");
    __asm    push [esp+4]
    __asm    ret
}

int main(int argc, char *argv[])
{
    stackbuild(somefunc);

    printf("exit main...\n");
    return 0;
}