gmcl_samurai_win32/samurai.cpp
2017-05-14 00:07:42 +03:00

183 lines
No EOL
3.8 KiB
C++

#include "samurai.h"
#include "memobj.h"
#include "struct.h"
int lGetModuleHandle(CLuaState* L)
{
L->CheckType(1,STRING);
L->PushInteger((int)GetModuleHandleA(L->GetString(1)));
return 1;
}
int lGetProcAddress(CLuaState* L)
{
L->CheckType(1,NUMBER);
L->CheckType(2,STRING);
L->PushInteger((int)GetProcAddress((HMODULE)L->GetInteger(1),L->GetString(2)));
return 1;
}
__declspec(naked) int VStdCall(int func,int stack) //StdCall
{
__asm
{
push ebp
mov ebp,esp
mov eax,[func]
mov esp,[stack]
call eax
mov esp,ebp
pop ebp
retn
}
}
int lInvoke(CLuaState* L)
{
DWORD dwFunc,dwData;
int argnum;
int* s_ptr;
char stack[10240];
s_ptr = (int*)&stack[10240];
memset(stack,'\0',10240);
L->CheckType(1,NUMBER);
dwFunc = (DWORD)L->GetInteger(1);
argnum = L->GetTop();
for(int i = argnum; i != 1; i--)
{
int type = L->Type(i);
switch(type)
{
case NUMBER:
dwData = L->GetInteger(i);
break;
case STRING:
dwData = (DWORD)L->GetString(i);
break;
case TBOOLEAN:
dwData = (DWORD)L->GetBool(i);
break;
default:
fprintf(stderr,"%d invalid type!\n",i);
}
s_ptr--;
*s_ptr = dwData;
}
L->PushInteger(VStdCall(dwFunc,(int)s_ptr));
return 1;
}
void Export2Table(CLuaState* L,const char* name)
{
PIMAGE_DOS_HEADER DosHeader;
PIMAGE_NT_HEADERS NtHeader;
PIMAGE_SECTION_HEADER SecHeader;
PIMAGE_EXPORT_DIRECTORY Exports;
PIMAGE_DATA_DIRECTORY Data;
HMODULE hDll;
DWORD dwLocal;
char* text,*end,*len;
char funcName[MAX_PATH];
LPVOID lpBase = (LPVOID)GetModuleHandle(name);
DosHeader = (PIMAGE_DOS_HEADER)lpBase;
NtHeader = (PIMAGE_NT_HEADERS)((DWORD)lpBase + DosHeader->e_lfanew);
SecHeader = IMAGE_FIRST_SECTION(NtHeader);
Data = (PIMAGE_DATA_DIRECTORY)(&NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]);
Exports = (PIMAGE_EXPORT_DIRECTORY)((DWORD)lpBase + Data->VirtualAddress);
L->CreateTable();
PDWORD pdwFunctions = (PDWORD)((DWORD)lpBase+Exports->AddressOfFunctions);
const char** Names = (const char**)((DWORD)lpBase+Exports->AddressOfNames);
unsigned short* ordinal = (unsigned short*)((DWORD)lpBase+Exports->AddressOfNameOrdinals);
for(int i = 0; i < Exports->NumberOfNames; i++)
{
const char* name = ((DWORD)lpBase+Names[i]);
unsigned short ord = ordinal[i];
dwLocal = (DWORD)lpBase+pdwFunctions[ord];
DWORD dwNew = (DWORD)GetProcAddress((HMODULE)lpBase,name);
if(dwLocal >= (DWORD)Exports && dwLocal <= (DWORD)Exports + Data->Size)
{
text = (char*)dwLocal;
len = (char*)(text+strlen(text));
memset(funcName,'\0',MAX_PATH);
if(!(end = (char*)strchr(text,'.')))
continue;
memcpy(funcName,text,(size_t)(end-text));
strcat(funcName,".dll");
if(!(hDll = GetModuleHandle(funcName)))
continue;
end++;
memcpy(funcName,end,(len-end));
dwLocal = (DWORD)GetProcAddress(hDll,funcName);
}
L->PushInteger(dwLocal);
L->SetField(-2,name);
}
}
int lExport2Table(CLuaState* L)
{
L->CheckType(1,STRING);
Export2Table(L,L->GetString(1));
return 1;
}
int Samurai_Open(CLuaState* L)
{
L->CreateTable();
L->PushCFunction(lGetModuleHandle);
L->SetField(-2,"GetModuleHandle");
L->PushCFunction(lGetProcAddress);
L->SetField(-2,"GetProcAddress");
L->PushCFunction(lExport2Table);
L->SetField(-2,"ExportTable");
L->PushCFunction(lMemObj_Create);
L->SetField(-2,"Alloc");
L->PushCFunction(Struct_FromPointer);
L->SetField(-2,"StructFromPointer");
L->SetGlobal("samurai");
L->PushCFunction(lInvoke);
L->SetGlobal("invoke");
Export2Table(L,"kernel32.dll");
L->SetGlobal("kernel32");
Export2Table(L,"user32.dll");
L->SetGlobal("user32");
L->PushInteger(0);
L->SetGlobal("NULL");
return 0;
}
int Samurai_Close(CLuaState* L)
{
L->PushNil();
L->SetGlobal("samurai");
L->PushNil();
L->SetGlobal("invoke");
L->PushNil();
L->SetGlobal("NULL");
return 0;
}