Is it possible, in a windows program, to write machine code in memory and then be able to run that code? If not, could one build a dll with a function in it, then load the dll from the same program, and run that function?
This is a discussion on self-writing code? within the C++ Programming forums, part of the General Programming Boards category; Is it possible, in a windows program, to write machine code in memory and then be able to run that ...
Is it possible, in a windows program, to write machine code in memory and then be able to run that code? If not, could one build a dll with a function in it, then load the dll from the same program, and run that function?
Yes, that's what a DLL is, it is loaded once and is used by many apps or many instances of one app but the DLL is loaded only once.
My Avatar says: "Stay in School"
Rocco is the Boy!
"SHUT YOUR LIPS..."
I think that he wants to know how to be able to have a user execute code at run-time.Originally posted by OneStiffRod
Yes, that's what a DLL is, it is loaded once and is used by many apps or many instances of one app but the DLL is loaded only once.
Naturally I didn't feel inspired enough to read all the links for you, since I already slaved away for long hours under a blistering sun pressing the search button after typing four whole words! - Quzah
You. Fetch me my copy of the Wall Street Journal. You two, fight to the death - Stewie
That's what a program does, it EXECUTES machine code at run-time.
If he wants to know whether code can be CREATED in real time - u need to REAL-TIME COMPILE IT. It needs to be compiled into machine code before it can be run.
My Avatar says: "Stay in School"
Rocco is the Boy!
"SHUT YOUR LIPS..."
Sure, anything's possible. But there's no documented way to do that, as far as I know. One way you might do it would be to generate the bytecode, stuff it into the appropriate headers, and then use a system call to run the program from a file you've generated. Otherwise, you're looking at some sort of assembly hack probably...
Code:int main(void){srand(time(0));for(double l=rand(),l0=0,l00=0;;l0+=0.1){for(double l000=0;l000 <1;l000+=.001,l+=((double)rand()/RAND_MAX)/0x64,l00+=((sin(l*0x8*atan(l0)*l000-(l0*0x8*atan (l)))*0.5)+0.5)){l00-=floor(l00);for(size_t l0000=0,l00000=(size_t)(0x50*(l00));l0000<l00000;++l0000 )putchar(0x20);putchar(0x61+(int)((double)rand()/RAND_MAX*0x1a));putchar('\n');}}return 0;}
You could always make the program generate assembly code and then run it through an assembler.
YES, just like a COMPILER
My Avatar says: "Stay in School"
Rocco is the Boy!
"SHUT YOUR LIPS..."
Here's a way:
Compile without optimizations.
Code:unsigned char data[10000]; //Fill the memory with no-ops for (int i=0;i<10000;++i) data[i] = 0x90; //NOP data[9999] = 0xC3; // RET //Create a function pointer to the memory void (__stdcall*pf)() = reinterpret_cast<void(__stdcall*)()>(data); //Execute the memory pf();
Last edited by Sang-drax : Tomorrow at 02:21 AM. Reason: Time travelling
Nice solution.![]()
Code:int main(void){srand(time(0));for(double l=rand(),l0=0,l00=0;;l0+=0.1){for(double l000=0;l000 <1;l000+=.001,l+=((double)rand()/RAND_MAX)/0x64,l00+=((sin(l*0x8*atan(l0)*l000-(l0*0x8*atan (l)))*0.5)+0.5)){l00-=floor(l00);for(size_t l0000=0,l00000=(size_t)(0x50*(l00));l0000<l00000;++l0000 )putchar(0x20);putchar(0x61+(int)((double)rand()/RAND_MAX*0x1a));putchar('\n');}}return 0;}
Yes its possible.Originally posted by genghis
Is it possible, in a windows program, to write machine code in memory and then be able to run that code?
You can set the EIP register of an intel based chip (and amd) on a windows machine to a portion of your memory using the SetThreadContext API........but doing so on the calling thread is undefined...so you should create a seperate, stalled thread and use that...resume the thread after the call...
I did this a while ago and posted the code on my site (which is now pretty much gone)....but here's my code....it uses VC++6.....but I guess it should work with other Win compilers - though I havent tested it.....it's real messy code (learning as I went along) but it works
Its a little tedious though...as you cant just copy reverse engineered code into the memory....you need to alter the jump tables and function addresses as well as the address of variables like the string used in my messageboxCode:////////////////////////////////////////// // Dynamic Assembly // // // by Fordy May 2002 // // // // This program is a sort of Obfuscated "Hello World" that // implements API calls by dynamically writing handcrafted // opcode to a region in memory, and then creating a thread // and pointing it to that opcode. // // // Copyright ©2002, Rob J Ford, robjford.com // All rights reserved.. // // Compile list:- // // Make sure project is a normal Win32 Application // Tested using VC++6 on the Windows 2000 platform // Not tested on any other platform!!!!! // // Definitions and preambles // #include <windows.h> int Assemble(void); //Creates opcodes to create MessageBox /////////////////////////////////////////////////////////////// //Class that represents a region in data that holds dynamically //generated opcodes and small lookup jump table // class HELLO{ public: UCHAR NULL1[2], MEMPOS1[5], MEMPOS2[5], NULL2[2], CALL1[5], NULL3[2], CALL2[5], JUMP1[6], JUMP2[6]; DWORD JUMPLOC1, JUMPLOC2; }Hello; /*MessageBox Text & Caption*/ char szMessage[] = "HelloWorld", szCaption[] = "Obfuscated!!!\nBy Rob J Ford\nMay 2002"; HMODULE hModKern,hModUser;//Handles of libraries loaded /////////////////////////////////////////////////////////////// //Main entry point.....Create opcodes in memory, create thread in //suspended state, jig around with EIP on thread so it pointes to //my opcode.....then....well....Rock n Roll // int WINAPI WinMain(HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nShowState){ HANDLE hThread,hThreadAccess; DWORD dwThreadID; CONTEXT cont; char szTrace[256]; /*Create the opcodes & lookups and store in memory*/ if(Assemble()) return 0; /*Create a suspended thread with no start point*/ hThread = CreateThread(NULL,0,NULL,NULL,CREATE_SUSPENDED, &dwThreadID); if(hThread == NULL){ MessageBox(HWND_DESKTOP,"Could not create thread", "Error",MB_OK | MB_ICONEXCLAMATION); return 1; } /*Redifine handle to allow me to get & set contects*/ DuplicateHandle(GetCurrentProcess(),hThread, GetCurrentProcess(),&hThreadAccess, THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | SYNCHRONIZE | THREAD_ALL_ACCESS,0,0); /*Access to most usefull registers*/ cont.ContextFlags = CONTEXT_FULL; /*Get the registers & flag of the created thread*/ if(!GetThreadContext(hThreadAccess,&cont)){ MessageBox(HWND_DESKTOP,"Could not load context", "Error",MB_OK | MB_ICONEXCLAMATION); return 1; } /*Set thread entry point to start of my opcode block*/ cont.Eip = (unsigned long)&Hello.NULL1[0]; cont.ContextFlags = CONTEXT_FULL; /*Set thread context*/ if(!SetThreadContext(hThreadAccess,&cont)){ MessageBox(HWND_DESKTOP,"Could not set context", "Error",MB_OK | MB_ICONEXCLAMATION); return 1; } /*Launch the thread and wait for it to exit*/ if(ResumeThread(hThreadAccess) != 0xFFFFFFFF) WaitForSingleObject(hThread, INFINITE); else{ wsprintf(szTrace,"Could not start thread\nError = %d", GetLastError()); MessageBox(HWND_DESKTOP,szTrace, "Error",MB_OK | MB_ICONEXCLAMATION); } /*No need.... but free up the libs*/ FreeLibrary(hModKern); FreeLibrary(hModUser); return 0; } /////////////////////////////////////////////////////////////// //Function creates links to 2 API calls dynamically and stores //info in memory as opcode....it also implements those functions //to display MessageBox and then finish thread // int Assemble(void){ UCHAR *pointer = 0,*pointer2 = 0; int j; union MYUNION{ UINT uiMemPos; UCHAR ucMemPos; }MyUnion; /*Set basic of opcodes*/ pointer = Hello.NULL1; *pointer = pointer[12] = pointer[19] = 'j';//push NULL start pointer[1] = pointer[13] = pointer[20] = 0;//push NULL end pointer[2] = pointer[7] = 'h'; //push mem start pointer[14] = pointer[21] = 232;//call start pointer[26] = pointer[32] = 255;//First part JUMP pointer[27] = pointer[33] = '%';//Second part JUMP /*Calculate distance between calls*/ Hello.CALL1[1] = (UINT)&Hello.JUMP1 - (UINT)&Hello.NULL3; Hello.CALL2[1] = (UINT)&Hello.JUMP2 - (UINT)&Hello.JUMP1; /*Set rest of call opcode to zero ..(debug help...not important)*/ for(j = 2;j<5;j++) Hello.CALL1[j] = Hello.CALL2[j] = 0; /*Get location of message*/ MyUnion.uiMemPos = (UINT)&szMessage; pointer = &Hello.MEMPOS1[1]; pointer2 = &MyUnion.ucMemPos; /*Copy to push statement (2nd param of MessageBoxA)*/ for(j = 0;j<4;j++) pointer[j] = pointer2[j]; /*Do as above for caption (3rd Param)*/ MyUnion.uiMemPos = (UINT)&szCaption; pointer = &Hello.MEMPOS2[1]; pointer2 = &MyUnion.ucMemPos; for(j = 0;j<4;j++) pointer[j] = pointer2[j]; /*Load for MessageBoxA*/ hModUser = LoadLibrary("user32.dll"); /*Load for ExitThread*/ hModKern = LoadLibrary("kernel32.dll"); if(hModKern == NULL || hModUser == NULL){ MessageBox(HWND_DESKTOP,"Could not load modules", "Error",MB_OK | MB_ICONEXCLAMATION); return 1; } /*Find memory location of MessageBox func*/ /*Copy that location to the first jmp lookup*/ Hello.JUMPLOC1 = (UINT)GetProcAddress(hModUser, "MessageBoxA"); if(Hello.JUMPLOC1 == NULL){ MessageBox(HWND_DESKTOP,"Could not locate procs", "Error",MB_OK | MB_ICONEXCLAMATION); return 1; } /*Move location of lookup to the first jmp stat*/ MyUnion.uiMemPos = (UINT)&Hello.JUMPLOC1; pointer2 = &MyUnion.ucMemPos; pointer = Hello.JUMP1; pointer += 2; for(j = 0;j<4;j++) pointer[j] = pointer2[j]; /*Same as above, but for ExitThread*/ Hello.JUMPLOC2 = (UINT)GetProcAddress(hModKern, "ExitThread"); if(Hello.JUMPLOC2 == NULL){ MessageBox(HWND_DESKTOP,"Could not locate procs", "Error",MB_OK | MB_ICONEXCLAMATION); return 1; } MyUnion.uiMemPos = (UINT)&Hello.JUMPLOC2; pointer2 = &MyUnion.ucMemPos; pointer = Hello.JUMP2; pointer += 2; for(j = 0;j<4;j++) pointer[j] = pointer2[j]; return 0; }
To answer the original question:
I think a DLL would be better.
You learn a lot by pushing limits, though.
Last edited by Sang-drax : Tomorrow at 02:21 AM. Reason: Time travelling
Thanks, I appreciate the help.
If you wanted to know, I'm trying to work on a project in which I accept a string from the user, such as "|x^2 + max(x, 5, y)|" and then try to compile a function that the programmer can call with the variables as parameters (in this case x and y). I'm doing it for practice as well as its future use considering I tend to use math quite a bit.
Dammit, Fordy, your code crashed my computer and erased my hard drive!j/k
Interesting solution, BTW.
Code:int main(void){srand(time(0));for(double l=rand(),l0=0,l00=0;;l0+=0.1){for(double l000=0;l000 <1;l000+=.001,l+=((double)rand()/RAND_MAX)/0x64,l00+=((sin(l*0x8*atan(l0)*l000-(l0*0x8*atan (l)))*0.5)+0.5)){l00-=floor(l00);for(size_t l0000=0,l00000=(size_t)(0x50*(l00));l0000<l00000;++l0000 )putchar(0x20);putchar(0x61+(int)((double)rand()/RAND_MAX*0x1a));putchar('\n');}}return 0;}
Then I advice you to forget about machine code (for now). A nice way to gain speed when evaluating expression repeatedly is to convert to RPN.Originally posted by genghis
I'm trying to work on a project in which I accept a string from the user, such as "|x^2 + max(x, 5, y)|" and then try to compile a function that the programmer can call with the variables as parameters (in this case x and y).
3 + x * 2 - y
becomes
3 4 x * + y -
When the RPN is generated, the expression can be evaluated fast for different values of x and y.
Last edited by Sang-drax : Tomorrow at 02:21 AM. Reason: Time travelling
If you want to cheat, you can use yacas. It is a CAS, but also comes with a dll you can load into your program and do things lik:
yacas.eval("x^2+2");
Depending on how complex of stuff you want, writing this yourself will not be a super easy task. I have an expression parser that takes an infix notion and converts it to postfix, you can PM me if you would like it.