1
0
Fork 0
x64dbg/x64_dbg_dbg/assemble.cpp

193 lines
5.3 KiB
C++

#include "assemble.h"
char nasmpath[deflen]="";
static bool issegment(const char* str)
{
if(!strncasecmp(str, "gs", 2))
return true;
if(!strncasecmp(str, "fs", 2))
return true;
if(!strncasecmp(str, "es", 2))
return true;
if(!strncasecmp(str, "ds", 2))
return true;
if(!strncasecmp(str, "cs", 2))
return true;
if(!strncasecmp(str, "ss", 2))
return true;
return false;
}
void intel2nasm(const char* intel, char* nasm)
{
char temp[256]="";
memset(temp, 0, sizeof(temp));
int len=strlen(intel);
for(int i=0,j=0; i<len; i++) //fix basic differences and problems
{
if(!strncasecmp(intel+i, "ptr", 3)) //remove "ptr"
{
i+=2;
if(intel[i+1]==' ')
i++;
continue;
}
else if(!strncasecmp(intel+i, " ", 2)) //remove double spaces
continue;
else if(intel[i]=='\t') //tab=space
{
j+=sprintf(temp+j, " ");
continue;
}
j+=sprintf(temp+j, "%c", intel[i]);
}
len=strlen(temp);
for(int i=0,j=0; i<len; i++)
{
if(temp[i]==' ' and temp[i+1]==',')
continue;
else if(temp[i]==',' and temp[i+1]==' ')
{
j+=sprintf(nasm+j, ",");
i++;
continue;
}
else if(issegment(temp+i) and temp[i+2]==' ')
{
j+=sprintf(nasm+j, "%c%c", temp[i], temp[i+1]);
i+=2;
continue;
}
else if(temp[i]==':' and temp[i+1]==' ')
{
j+=sprintf(nasm+j, ":");
i++;
continue;
}
j+=sprintf(nasm+j, "%c", temp[i]);
}
len=strlen(nasm);
for(int i=0,j=0; i<len; i++)
{
if(issegment(nasm+i) and nasm[i+2]==':' and nasm[i+3]=='[')
{
j+=sprintf(temp+j, "[%c%c:", nasm[i], nasm[i+1]);
i+=3;
continue;
}
j+=sprintf(temp+j, "%c", nasm[i]);
}
strcpy(nasm, temp);
}
bool assemble(const char* instruction, unsigned char** outdata, int* outsize, char* error, bool x64)
{
if(!instruction or !outsize)
return false;
char tmppath[MAX_PATH]="";
char tmpfile[MAX_PATH]="";
char outfile[MAX_PATH]="";
if(!GetTempPathA(MAX_PATH, tmppath) or !GetTempFileNameA(tmppath, "dbg", 0, tmpfile) or !GetTempFileNameA(tmppath, "dbg", 0, outfile))
{
DeleteFileA(outfile);
DeleteFileA(tmpfile);
return false;
}
char* asmfile=(char*)emalloc(strlen(instruction)+9);
if(x64)
strcpy(asmfile, "BITS 64d\n");
else
strcpy(asmfile, "BITS 32d\n");
strcat(asmfile, instruction);
HANDLE hFile=CreateFileA(tmpfile, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if(hFile==INVALID_HANDLE_VALUE)
{
if(error)
strcpy(error, "Failed to create asmfile!");
efree(asmfile);
DeleteFileA(outfile);
DeleteFileA(tmpfile);
return false;
}
DWORD written=0;
if(!WriteFile(hFile, asmfile, strlen(asmfile), &written, 0))
{
if(error)
strcpy(error, "Failed to write asmfile!");
efree(asmfile);
CloseHandle(hFile);
DeleteFileA(outfile);
DeleteFileA(tmpfile);
return false;
}
efree(asmfile);
CloseHandle(hFile);
char cmdline[MAX_PATH*4]="";
sprintf(cmdline, "\"%s\" \"%s\" -o \"%s\"", nasmpath, tmpfile, outfile);
STARTUPINFO si;
memset(&si, 0, sizeof(si));
si.cb=sizeof(si);
PROCESS_INFORMATION pi;
if(!CreateProcessA(0, cmdline, 0, 0, false, CREATE_NO_WINDOW, 0, 0, &si, &pi))
{
if(error)
strcpy(error, "Failed to start NASM!");
DeleteFileA(outfile);
DeleteFileA(tmpfile);
return false;
}
DWORD exitCode=STILL_ACTIVE;
do
GetExitCodeProcess(pi.hProcess, &exitCode);
while(exitCode==STILL_ACTIVE);
if(exitCode) //nasm failed
{
if(error)
strcpy(error, "NASM reported a failure!");
DeleteFileA(outfile);
DeleteFileA(tmpfile);
return false;
}
hFile=CreateFileA(outfile, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
if(hFile==INVALID_HANDLE_VALUE)
{
if(error)
strcpy(error, "Failed to open outfile!");
DeleteFileA(outfile);
DeleteFileA(tmpfile);
return false;
}
int filesize=GetFileSize(hFile, 0);
if(!filesize)
{
if(error)
strcpy(error, "No result in outfile!");
CloseHandle(hFile);
DeleteFileA(outfile);
DeleteFileA(tmpfile);
return false;
}
*outsize=filesize;
unsigned char* out=(unsigned char*)emalloc(filesize);
DWORD read=0;
if(!ReadFile(hFile, out, filesize, &read, 0))
{
if(error)
strcpy(error, "Failed to read outfile!");
efree(out);
CloseHandle(hFile);
DeleteFileA(outfile);
DeleteFileA(tmpfile);
return false;
}
if(outdata)
*outdata=out;
else
efree(out);
CloseHandle(hFile);
DeleteFileA(outfile);
DeleteFileA(tmpfile);
return true;
}