VC的编译器能将数据与代码编译到一起

如何将中间的全局变量(数据)编译到代码中间去呢?

#include <windows.h>

#include "apidef.h"

//#pragma comment (linker, "/filealign:0x200")
#pragma comment(linker, "/SECTION:.text,REW" ) //设PE节:.text,可读可执行
#pragma comment(linker, "/MERGE:.data=.text") //合并到.text
#pragma comment(linker, "/MERGE:.rdata=.text")//合并到.text
#pragma comment(linker, "/subsystem:windows /entry:main")

/*
#pragma comment(linker, "/SECTION:aaa,REW")

#pragma code_seg("aaa$A")
*/


ULONG __declspec(naked) GetBeginAddr()
{
    __asm
    {
        call lbl_Next
lbl_Next:
        pop eax
        sub eax, 5
        ret
    }
}
///
//全局变量


PFNMESSAGEBOX g_pfnMessageBox;
char g_Msg[]="hello world!";
char g_Title[]="Success!";


PVOID GetGlobalVarAddr(PVOID pVar)
{
    PVOID pCurAddr = NULL;
    __asm
    {
Start:
        call lbl_Next
lbl_Next:
        pop eax
        sub eax, 5
        sub eax, offset Start
        add eax, pVar
        mov pCurAddr, eax
    }
    return pCurAddr;
}


///
//开始的shell

void Dotest2()
{
//这里能够正确执行
    return;
}

void Dotest()
{
    PFNMESSAGEBOX pfnMessageBox;
    NONECALL pfnDotest2;

    pfnDotest2 = (NONECALL) GetGlobalVarAddr(&Dotest2);
    pfnDotest2();
    pfnMessageBox = GetGlobalVarAddr(&g_pfnMessageBox);
    pfnMessageBox (NULL,GetGlobalVarAddr(g_Msg),GetGlobalVarAddr(g_Title),NULL);
    return;
}



ULONG __declspec(naked) GetEndAddr()
{
    __asm
    {
        call lbl_Next
lbl_Next:
        pop eax
        add eax, 5
        ret
    }
}


//#pragma code_seg()

/
//主函数测试

int main()
{
    NONECALL pfnDotest;
    LPVOID pBuffer;
    DWORD shellsize;

    g_pfnMessageBox = (PFNMESSAGEBOX) MessageBox;
    shellsize = (DWORD)(GetEndAddr()-GetBeginAddr());
    pBuffer = VirtualAlloc(NULL,shellsize,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
    memcpy((void*)pBuffer,(const void*)GetBeginAddr,shellsize);
    pfnDotest = (NONECALL) ((ULONG)Dotest - GetBeginAddr() + (ULONG)pBuffer);
    pfnDotest();
    return 0;
}

头文件

#ifndef    _APIDEF_H
#define    _APIDEF_H

typedef int (__stdcall *PFNMESSAGEBOX) (HWND, LPCSTR, LPCSTR, UINT);

typedef void ( * NONECALL) ();

#endif


dubugman的答案

 

#include <windows.h>

#include "apidef.h"

#pragma comment(linker, "/SECTION:.text,REW" ) //设PE节:.text,可读可执行

//#pragma comment (linker, "/filealign:0x200")
/*
#pragma comment(linker, "/SECTION:.text,REW" ) //设PE节:.text,可读可执行
#pragma comment(linker, "/MERGE:.data=.text") //合并到.text
#pragma comment(linker, "/MERGE:.rdata=.text")//合并到.text
#pragma comment(linker, "/subsystem:windows /entry:main")
*/

/*
#pragma comment(linker, "/SECTION:aaa,REW")

#pragma code_seg("aaa$A")
*/

ULONG __declspec(naked) GetBeginAddr()
{
    __asm
    {
        call lbl_Next
lbl_Next:
        pop eax
            sub eax, 5
            ret
    }
}
///
//全局变量


/*
PFNMESSAGEBOX g_pfnMessageBox;
char g_Msg[]="hello world!";
char g_Title[]="Success!";
*/
#define Naked  __declspec( naked )

Naked VOID g_pfnMessageBox()
{
    __asm _emit 0x0
    __asm _emit 0x0
    __asm _emit 0x0
    __asm _emit 0x0
}

Naked VOID g_Msg()
{
    // hello world!
    __asm _emit 0x68
    __asm _emit 0x65
    __asm _emit 0x6c
    __asm _emit 0x6c
    __asm _emit 0x6f
    __asm _emit 0x20
    __asm _emit 0x77
    __asm _emit 0x6f
    __asm _emit 0x72
    __asm _emit 0x6c
    __asm _emit 0x64
    __asm _emit 0x21
    __asm _emit 0
}

Naked VOID g_Title()
{
    // Success!
    __asm _emit 0x53
    __asm _emit 0x75
    __asm _emit 0x63
    __asm _emit 0x63
    __asm _emit 0x65
    __asm _emit 0x73
    __asm _emit 0x73
    __asm _emit 0x21
    __asm _emit 0x0

}

PVOID GetGlobalVarAddr(PVOID pVar)
{
    PVOID pCurAddr = NULL;
    __asm
    {
Start:
        call lbl_Next
lbl_Next:
        pop eax
            sub eax, 5
            sub eax, offset Start
            add eax, pVar
            mov pCurAddr, eax
    }
    return pCurAddr;
}


///
//开始的shell

void Dotest2()
{
    //这里能够正确执行
    return;
}

void Dotest()
{
    PFNMESSAGEBOX pfnMessageBox;
    NONECALL pfnDotest2;

    pfnDotest2 = (NONECALL) GetGlobalVarAddr(&Dotest2);
    pfnDotest2();
    pfnMessageBox = (PFNMESSAGEBOX)GetGlobalVarAddr(&g_pfnMessageBox);
    pfnMessageBox (NULL,(LPCSTR)GetGlobalVarAddr(g_Msg),(LPCSTR)GetGlobalVarAddr(g_Title),NULL);
    return;
}



ULONG __declspec(naked) GetEndAddr()
{
    __asm
    {
        call lbl_Next
lbl_Next:
        pop eax
            add eax, 5
            ret
    }
}


//#pragma code_seg()

/
//主函数测试

int main()
{
    NONECALL pfnDotest;
    LPVOID pBuffer;
    DWORD shellsize;

    *((PULONG)g_pfnMessageBox) = (ULONG) MessageBox;
    shellsize = (DWORD)(GetEndAddr()-GetBeginAddr());
    pBuffer = VirtualAlloc(NULL,shellsize,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
    memcpy((void*)pBuffer,(const void*)GetBeginAddr,shellsize);
    pfnDotest = (NONECALL) ((ULONG)Dotest - GetBeginAddr() + (ULONG)pBuffer);
    pfnDotest();
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值