n7:C内嵌ASM动态调用函数(stdcall)



#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <memory>
#include <string>
#include <cstdarg>
#include <map>
#include <vector>
#include <windows.h>
using namespace std;

#define CCT_AALIGN				0x4
#define CCT_SALIGN				0x8
#define CCT_E_SUCCESS			0xF0000000
#define CCT_E_UNKNOWNTYPE 0xF0000001
#define CCT_E_WRONGNATYPE 0xF0000002
#define CCT_E_MULTRETUAN	0xF0000004
#define CCT_RT						0x10000000
#define CCT_UNK						0x1000
#define CCT_INT						0x1001
#define CCT_32						0x1002
#define CCT_DOUBLE				0x1004
#define CCT_64						0x1008
#define CCT_NA						0x1010
//----------------------------------------------------------------------------

struct cct { 
	unsigned t; 
	unsigned rn; 
	unsigned bc; 
	unsigned mc; 
	char* b; 
	cct* n;
	cct():t(CCT_UNK), rn(0), bc(0), mc(0), b(0), n(0){};
	void newbuf(unsigned size) { if (b) free(b); b=(char*)malloc(size); }
	virtual ~cct() { if (b) free(b); }
}; // end of cct
#define cct_astype(a,t) (t&)(*(t*)a.b)

//----------------------------------------------------------------------------
#define ASM_RET_SPACE(rtc,rta) \
	_asm				mov eax, dword ptr[rtc]\
	_asm				cmp eax, 4\
	_asm				jle rsD\
	_asm				sub esp, eax\
	_asm				mov dword ptr[rta], esp\
	_asm rsD:		\

#define ASM_RET_ADDR(rta) \
	_asm				push dword ptr[rta]\

#define ASM_SAVERETURN(v_buf, rtc) \
	_asm				mov edx, dword ptr[v_buf]\
	_asm				mov ecx, dword ptr[rtc]\
	_asm				cmp ecx, 4\
	_asm				jg rtL\
	_asm				mov dword ptr[edx], eax\
	_asm				jmp srD\
	_asm rtL:   cmp ecx, 0\
	_asm				jz srD\
	_asm				mov esi, dword ptr[eax]\
	_asm				mov dword ptr[edx], esi\
	_asm				add eax, 4\
	_asm				add edx, 4\
	_asm				sub ecx, 4\
	_asm				jmp rtL\
	_asm srD:		\

#define ASM_MOVE_32P(v_buf) \
	_asm				sub esp, 4\
	_asm				mov edx, dword ptr[v_buf]\
	_asm				mov eax, dword ptr[edx]\
	_asm				mov dword ptr[esp], eax\

#define ASM_MOVE_64P(v_buf) \
	_asm				sub esp, 8\
	_asm				mov ecx, esp\
	_asm				mov edx, dword ptr[v_buf]\
	_asm				mov eax, dword ptr[edx]\
	_asm				mov dword ptr[ecx], eax\
	_asm				add ecx, 4\
	_asm				mov edx, dword ptr[v_buf]\
	_asm				mov eax, dword ptr[edx+04h]\
	_asm				mov dword ptr[ecx], eax\

#define ASM_MOVE_naP(v_buf, v_bc, v_mc) \
	_asm				mov ecx, dword ptr[v_bc]\
	_asm				inc ecx\
	_asm				mov eax, 4\
	_asm				mul ecx\
	_asm				mov edx, dword ptr[v_buf]\
	_asm				sub esp, eax\
	_asm				mov esi, esp\
	_asm				dec ecx\
	_asm napL:	cmp ecx, 0\
	_asm				jz TAIL\
	_asm				mov eax, dword ptr[edx]\
	_asm				mov dword ptr[esi], eax\
	_asm				add edx, 04h\
	_asm				add esi, 04h\
	_asm				dec ecx\
	_asm				jmp napL\
	_asm TAIL:	mov ecx, dword ptr[v_mc]\
	_asm				cmp ecx, 3\
	_asm				jnz	M2\
	_asm				mov al, byte ptr[edx]\
	_asm				mov byte ptr[esi],al\
	_asm				inc edx\
	_asm				inc esi\
	_asm				mov ax, word ptr[edx]\
	_asm				mov word ptr[esi],ax\
	_asm				jmp naPD\
	_asm M2:		cmp ecx, 2\
	_asm				jnz M1\
	_asm				mov ax, word ptr[edx]\
	_asm				mov word ptr[esi],ax\
	_asm				jmp naPD\
	_asm M1:		cmp ecx, 1\
	_asm				jnz naPD\
	_asm				mov al, byte ptr[edx]\
	_asm				mov byte ptr[esi],al\
	_asm naPD: \


#define ASM_STDCALL_CALL(v_pfunc) \
	_asm call v_pfunc\

void cc_call(cct* a, void* p) {
	int err=0;
	int rtc=0;
	int rta=0;
	cct *r=0;
	int v_eax=0;
	char* v_rb=0;
	while (a&&!err) {
		char* b=a->b;
		int v_bc=a->bc; int v_mc=a->mc;
		if (a->t&CCT_RT) {
			if (rtc) { err=CCT_E_MULTRETUAN; }
			else {
				switch(a->t&~CCT_RT) {
					case CCT_INT: 
					case CCT_32: rtc=sizeof(int); break;
					case CCT_DOUBLE: 
					case CCT_64: rtc=sizeof(double); break;
					case CCT_NA: { 
						if (a->bc+a->mc) {rtc=(a->bc+1); rtc<<=2; }
						else { err=CCT_E_WRONGNATYPE; }
						} break;
					default: err=CCT_E_UNKNOWNTYPE;
				}
				if (rtc) { 
					r=a;
					r->newbuf(rtc);
					r->t=CCT_RT;
					v_rb=r->b;
					ASM_RET_SPACE(rtc, rta);
				}
			}
		} else {
			switch(a->t) {
				case CCT_INT: 
				case CCT_32: { 
					ASM_MOVE_32P(b);
					} break;
				case CCT_DOUBLE: 
				case CCT_64: { 
					ASM_MOVE_64P(b);
					} break;
				case CCT_NA: { 
					ASM_MOVE_naP(b, v_bc, v_mc);
					} break;
				default: err=CCT_E_UNKNOWNTYPE;
			}
		}
		a=a->n;
	}
	if (!err) { 
		if (rtc) {
			ASM_RET_ADDR(rta);
		}
		ASM_STDCALL_CALL(p);
		if (rtc) {
			ASM_SAVERETURN(v_rb, rtc);
		}
	} else { printf("err:\t%d\n", err); }
}

//----------------------------------------------------------------------------
struct Large1{ char c; short s; int i; };
struct Large2{ char c; double d; };
struct Large3{ char b[5]; };
struct Large4{ char b[4]; };
struct Large5{ char b[6]; };
struct Large6{ char b[13]; }; 
int aa(int a, Large1 l) { unsigned mass=0x10000000; return a+l.c+l.s+l.i; }
double bb(double a, char b) { return a+b; }
void __cdecl cc(double a) { printf("cc:\t%f\n", a); }
void __stdcall dd(Large2 a) { printf("dd:\t%f\n", a.d); }
void __stdcall ee(Large3 a) { printf("ee:\t%d\n", sizeof(Large3)); }
void __stdcall ff(short s, char c) { printf("ff:\t%d,%c\n", s, c); }
void __stdcall gg(const char* s) { printf("gg:\t%s\n", s); }
void __stdcall hh(void (__stdcall*p)(const char* s)) { printf("hh:\t0x%x\n", p); }
void __stdcall ii(int i) { printf("ii:\t%d\n", i); }
void __stdcall jj(double d) { printf("jj:\t%f\n", d); }
void __stdcall kk(Large4 l) { printf("kk:\t%s\n", l.b); }
void __stdcall ll(Large4 l) { printf("ll:\t%s\n", l.b); }
Large6 __stdcall mm(Large6 l) { 
	return l; 
	/*
		mov         eax,dword ptr [ebp+8]  
		mov         ecx,dword ptr [l]  
		mov         dword ptr [eax],ecx  
		mov         edx,dword ptr [ebp+10h]  
		mov         dword ptr [eax+4],edx  
		mov         ecx,dword ptr [ebp+14h]  
		mov         dword ptr [eax+8],ecx  
		mov         dl,byte ptr [ebp+18h]  
		mov         byte ptr [eax+0Ch],dl  
		mov         eax,dword ptr [ebp+8]  
	*/
}
Large6 __stdcall nn(Large6 l) { 
	int len=strlen(l.b);
	for(int i=0;i<len;++i) { l.b[i]+=1; }
	printf("nn:\t%s\n", l.b);
	return l;
}

int __stdcall oo() { printf("oo:\t99\n"); return 99; }

//----------------------------------------------------------------------------

int main() {
	{/* int gap=0x2468;
		Large1 l; l.c=0x40; l.s=0x24; l.i=0x68;
		unsigned mass=0x00000;
		gap=aa(0x123, l);
		double a=1.0;
		char b=0x20;
		a=bb(a,b);
	*/}
	{ double d=12.34;
		_asm {
			fld		qword ptr[d]
			sub		esp, 8
			fstp	qword ptr[esp]
			call  [cc]
			add		esp, 8 // __cdecl
		}
	} 
	{
		Large2 l2; l2.c=0x68; l2.d=56.78;
		/*
			sub         esp,10h  
			mov         eax,esp  
			mov         ecx,dword ptr [l]  
			mov         dword ptr [eax],ecx  
			mov         edx,dword ptr [ebp-24h]  
			mov         dword ptr [eax+4],edx  
			mov         ecx,dword ptr [ebp-20h]  
			mov         dword ptr [eax+8],ecx  
			mov         edx,dword ptr [ebp-1Ch]  
			mov         dword ptr [eax+0Ch],edx  
			call        dd
		 */ dd(l2);
	} 
	{
		Large3 l3;
		/*
			sub         esp,8  
			mov         eax,esp  
			mov         ecx,dword ptr [l3]  
			mov         dword ptr [eax],ecx  
			mov         dl,byte ptr [ebp-34h]  
			mov         byte ptr [eax+4],dl  
			call        ee
		*/ ee(l3);
	} 
	{
		short s=0x45; char c='A';
		/*
			movzx       eax,byte ptr [c]  
			push        eax  
			movzx       ecx,word ptr [s]  
			push        ecx  
			call        ff
		*/ ff(s, c);
	} 
	{
		const char* s="abc";
		/*
			mov         eax,dword ptr [ebp-5Ch]  
			push        eax  
			call        gg
		*/ gg(s);
	}
	{
		/*
		push        offset gg
		call        hh
		*/ hh(&gg);
	}
	/*
	_asm {
		push 999
		call dword ptr[Sleep]
	} */
	{
		cct p;
		p.newbuf(sizeof(int));
		p.t=CCT_INT;
		cct_astype(p, int)=13579;
		cc_call(&p, &ii);
	}
	{
		cct p;
		p.newbuf(sizeof(double));
		p.t=CCT_DOUBLE;
		cct_astype(p,double)=5678.9;
		cc_call(&p, &jj);
	}
	{
		cct p;
		p.newbuf(sizeof(Large4));
		p.t=CCT_32;
		strcpy(p.b, "abc");
		cc_call(&p, &kk);
	}
	{
		cct p;
		p.newbuf(sizeof(Large5));
		p.t=CCT_NA;
		p.bc=1;
		p.mc=2;
		strcpy(p.b, "abcde");
		//cc_call(&p, &ll);
	}
	{
		Large6 l;
		strcpy(l.b, "god");
		Large6 r=mm(l);
		printf("mm:\t%s\n", r.b);
	}
	{
		cct pr; pr.t=CCT_NA+CCT_RT;
		pr.bc=3; pr.mc=1;

		cct p; 
		p.newbuf(sizeof(Large6));
		p.t=CCT_NA; p.bc=3; p.mc=1;
		strcpy(p.b, "abcdefg");

		pr.n=&p;
		cc_call(&pr, &nn);
		printf("nn:\t%s\n", pr.b);
	}
	{
		cct pr2; pr2.t=CCT_INT+CCT_RT;
		cc_call(&pr2, &oo);
		printf("oo:\t%d\n", *pr2.b+12);
	}
	printf("END!\n");
	return 0;
}

//----------------------------------------------------------------------------
//
#define CCT_ROUND(s,round) ((s)+(round)-1)&~((round)-1)
int cct_align(int PackAlign, const vector<int>& List) {
	int result=0;
	/*
	int count=List.size();
	if (count > 0) {
		int i=1;
		int max_size=0;
		int min_size=0;
		for (auto n : List) {
			max_size=max(max_size,n);
			min_size=min(PackAlign,n);
			if (i) { i=0; result=n; printf("-%d\n", result); }
			else {
				result=CCT_ROUND(result+n, min_size);
				printf("*%d\n", result);
			}
		}
		min_size=min(PackAlign,max_size);
		result=CCT_ROUND(result, min_size);
		printf("+%d\n", result);
	}
	*/
	return result;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值