I have problems with inline assembly in visual c++ 2010 Ultimate (Windows 7 Professional). All my inline assemblies don't work, when I use chars, DWORD strings etc etc... So I copied this code from MSDN in my console application:
// InlineAssembler_Calling_C_Functions_in_Inline_Assembly.cpp
// processor: x86
#include <stdio.h>
char format[] = "%s %s\n";
char hello[] = "Hello";
char world[] = "world";
int main( void )
{
__asm
{
mov eax, offset world
push eax
mov eax, offset hello
push eax
mov eax, offset format
push eax
call printf
//clean up the stack so that main can exit cleanly
//use the unused register ebx to do the cleanup
pop ebx
pop ebx
pop ebx
}
}
I have nothing except those lines in my application, result: The string doesn't get printed and the application crashs. Any ideas why this happens?
Project + Properties, C/C++, Code Generation, select /MTd. Repeat for the Release configuration, select /MT.
If you want to make it work with the non-static version of the CRT then you'll need to write the call like this:
call dword ptr printf
Exports from a DLL need to be called indirectly.
I am assuming that popping into ebx is the reason. It is Your responsibility to maintain the integrity of all registers, excluding eax. Try popping into eax instead.
Related
I need to suppress Buffer Security Check (/GS) feature (MSVC) for some functions but not for entire Project as /GS- doing.
MSVSC documentation https://learn.microsoft.com/en-us/cpp/preprocessor/strict-gs-check?view=vs-2017 prompts to use #pragma strict_gs_check(off). Unfortunately, it doesn't work for me - I still see the "cookies" in the assembly. Any help, please.
This is simplest code to reproduce, godbold link here: https://godbolt.org/z/gYiGam
#include <memory>
struct Tmp {
char v[8];
};
//#pragma check_stack(off)
#pragma strict_gs_check(off)
int make1(Tmp& a)
{
Tmp r;
return memcmp(&r, &a, sizeof(r));
}
//result
//-------------------------
pop esi
mov ecx, DWORD PTR __$ArrayPad$[esp+12]
xor ecx, esp
call #__security_check_cookie#4
add esp, 12 ; 0000000cH
ret 0
$LN6#make1:
mov ecx, DWORD PTR __$ArrayPad$[esp+16]
sbb eax, eax
pop esi
xor ecx, esp
or eax, 1
call #__security_check_cookie#4
add esp, 12 ; 0000000cH
ret 0
int make1(Tmp &) ENDP ; make1
I don't think you can disable it that way. The strict GS checking is a request to the compiler to add stricter checks, to functions that would otherwise not have it.
In other words, /GS controls whether GS buffer checking is done and the pragma simply controls how aggressive it is.
If you want to disable it entirely for a specific function, you should use __declspec(safebuffers) on said function (see
https://learn.microsoft.com/en-us/cpp/cpp/safebuffers?view=vs-2017). This is an indication that you don't want checking at all.
You can move all the functions that not need checks to a single file and then use /GS- only for this file.
Also take a look to the /RTCs /RTCu /RTC1 settings
how in c++ visual can i set labels for when i need to use inline assembly, so it would look like something like this for example...
__asm
{
PUSH EAX
PUSH VAR1
MOV ECX,DWORD PTR DS:[VAR2]
CALL DWORD PTR DS:[VAR3]
JMP VAR4
}
where the VAR varables link to a value or address?
i have tried the following
DWORD VAR2 = 0x991770; //0x991770 is the location of the function
__asm
{
..code
MOV ECX,DWORD PTR DS:[VAR2]
..code
}
but then the app crashes, how is this done?
Use offset variableName to access variables from inline assembly. See reference here.
Example:
char format[] = "%s %s\n";
char hello[] = "Hello";
char world[] = "world";
int main( void )
{
__asm
{
mov eax, offset world
push eax
mov eax, offset hello
push eax
mov eax, offset format
push eax
call printf
//clean up the stack so that main can exit cleanly
//use the unused register ebx to do the cleanup
pop ebx
pop ebx
pop ebx
}
}
C variable names are visible in inline assembly. So if you need data access, just write the var name:
int var2 = 3;
__asm
{
mov ecx, var2
That will compile to the appropriate memory access statement.
For code labels - you just declare them, like in real assembly:
Label1:
mov ecx, 0
jmp Label1
External functions are seen as labels, too. Name mangling applies, though.
If you need the numeric value of the current IP as a general purpose register, there's no direct command, but a very simple workaround is available:
call Next
Next:
pop eax ; eax now is the value of IP at the current point
Oh, and forget about the ds: stuff. You're in Flatland now - check your segment registers at the door.
I am by all means no assembler expert, and my knowledge on this topic is rather shallow, but I was curious on what the Microsoft VC++ Compiler does in a simple function call that does nothing else but returning a value.
Let us have the following function:
unsigned long __stdcall someFunction ( void * args) {
return 0;
}
Now, I know that with __stdcall calling convention the CALLEE is responsible for stack unwinding, and with __cdecl the CALLER of the function takes care of this. But for this example I would like to stick to the former.
With an non-optimized debug build I saw that the following output is being produced:
unsigned long __stdcall someFunction (void * args) {
00A31730 push ebp
00A31731 mov ebp,esp
00A31733 sub esp,0C0h
00A31739 push ebx
00A3173A push esi
00A3173B push edi
00A3173C lea edi,[ebp-0C0h]
00A31742 mov ecx,30h
00A31747 mov eax,0CCCCCCCCh
00A3174C rep stos dword ptr es:[edi]
return 0;
00A3174E xor eax,eax
}
00A31750 pop edi
00A31751 pop esi
00A31752 pop ebx
00A31753 mov esp,ebp
00A31755 pop ebp
00A31756 ret 4
I would thank anyone to explain this snippet of code for me if possible. I know that the xor statement actually resets the eax register to produce the zero return value. Also the ret 4 is self-explanatory to me. I think the edi, esi and ebx registers are pushed before and popped after to save the original state, so that the function can use them freely maybe. But for the rest - I have no clue.
Any answer is very much appreciated! :)
Thanks!
So you're asking what these lines do:
00A3173C lea edi,[ebp-0C0h]
00A31742 mov ecx,30h
00A31747 mov eax,0CCCCCCCCh
00A3174C rep stos dword ptr es:[edi]
In Visual C++ debugging runtime library, uninitialized stack memory is initialized to contain 0xCC bytes. This is what these instructions do.
At the beginning of the ASM code, there is the instruction sub esp,0C0h that allocates 0xC0 bytes for the stack. However, there is no local variables used in this function, so where does this come from? It's for Edit+Continue support: you're able to add local variables and continue debugging.
The 0xCC opcode means the INT 3 x86 assembly instruction, so if you try to execute that code (accidentally due to a bug), the program will throw an INT 3 exception which will be handled by the debugger or OS. So it's not just some random value.
When I try to make an immediate call or jump in VC++ 2010 inline assembler
_asm
{
call 00405B90h;
jmp 00405B90h;
jmp far 00405B90h;
}
it generates an error
C2415: improper operand type
Is it possbile and how to do this?
So far I have a work around:
_asm
{
push 00405B90h; // This is a jump work around
call 00405B90h;
}
depending on what you want to call, either set a var to the address and do:
DWORD var = 0xDEADBEEF;
__asm jmp [var]
or, what I do:
__asm
{
mov eax,ModuleBase
add eax,RVA
call eax ;obviously call can be jmp
}
you can easily macro this(probably a good idea to add a register param):
#define JMP_IMM(x) __asm mov eax,x \
__asm jmp eax
Unfortunately MASM doesn't support relative calls to absolute addresses, and other assemblers like NASM can't do it for COFF object files either. So toolchain limitations force you to use this less efficient machine code with an indirect call or jmp.
How to write an absolute target for a near direct relative call/jmp in MASM
Error when calling function in user32.dll directly
__asm jmp fword ptr cs:[00405B90h]
I have an inline assembler function detects program runs on Virtual Machine or not. But in 64bit inline assembly is not available anymore, here x64 intrinsics now. Is there another way for detecting it?
Here is the code works for 32bit VMWare
bool IsInsideVMWare(void)
{
bool rc = true;
__try
{
__asm
{
push edx
push ecx
push ebx
mov eax, 'VMXh'
mov ebx, 0 // any value but not the MAGIC VALUE
mov ecx, 10 // get VMWare version
mov edx, 'VX' // port number
in eax, dx // read port
// on return EAX returns the VERSION
cmp ebx, 'VMXh' // is it a reply from VMWare?
setz [rc] // set return value
pop ebx
pop ecx
pop edx
}
}
__except(filter(GetExceptionCode()))
{
rc = false;
}
return rc;
}
Thanks to a responder i found a way creating a function using assembly language and separate these function as .asm file and adding it to my solution. Here is the problem :) I don't know how to convert these code properly to compile with masm (ml.exe) in VS.
This is a question for the MASM forum
http://www.masm32.com/board/index.php?
you are diving a little too deep for StackOverflow...