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]
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
When I've read the gcc documentation I assumed that the inline (or inline) keyword would remove the function call overhead.
As I qoute:
"
One way GCC can achieve this is to integrate that function's code into the code for its callers.
This makes execution faster by eliminating the function-call overhead; in addition, if any of the actual argument values are constant, their known values may permit simplifications at compile time so that not all of the inline function's code needs to be included.
" Gcc Manual 6.36
Thus I assumed that the following C code:
__inline__ int sum(int a, int b)
{
return a+b;
}
int add_one(int a)
{
return sum(a, 1);
}
would translate into
add_one:
mov eax, [ebp-4]
add eax, 0x01
retn
Instead of:
add_one:
push 0x01
push [ebp-4]
call sum
retn
As this doesn't work how I expected I would like to ask a question.
I have an object file with a function. It exports the symbol _my_func. I got the C code with the following code:
extern __inline__ _my_func
int main(int argc, char **argv)
{
_my_func(argv[1]);
_my_func(argv[2]);
}
How can I merge my object's code within my main function. Eg remove the call and the function overhead.
Thanks
Stolas
btw, even here ( What does __inline__ mean ? ) I noticed that it should remove the function overhead. But objdump says otherwise :S
Post Update:
Even with the following commands:
nasm -felf get42.s -o42.o
gcc O3 42.o main.c -o mybin.elf
objdump -d mybin.elf
I notice a little call like so:
<_get42>:
xor eax, eax
mov eax, 0x42
ret
<main>:
push ebp
mov ebp, esp
add esp, 0xfffffff0
call _get42
leave
ret
btw I do notice it removed the (mov ebp, esp etc) overhead in the function. But is that all it does? As I just want to remove the call with the actual code within the function.. As in eliminate the call, jmp or push, ret.
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.
"call 0x80482f0 <puts#plt>"? Just need help with one line of code in a 'hello world' program in x86 assembly.
NOTE: i'm running ubuntu linux while programming/debugging this, using gcc as the compiler and gdb for the debugger.
I am reading Hacking: The art of Exploitation V2 and I compiled this C program:
1 #include <stdio.h>
2
3 int main()
4 {
5 int i;
6 for(i=0; i<10; i++)
7 {
8 printf("Hello, world\n");
9 }
10 return 0;
into this program in assembly:
0x080483b4 <+0>: push ebp
0x080483b5 <+1>: mov ebp,esp
0x080483b7 <+3>: and esp,0xfffffff0
0x080483ba <+6>: sub esp,0x20
0x080483bd <+9>: mov DWORD PTR [esp+0x1c],0x0
0x080483c5 <+17>: jmp 0x80483d8 <main+36>
0x080483c7 <+19>: mov DWORD PTR [esp],0x80484b0
0x080483ce <+26>: call 0x80482f0 <puts#plt>
=> 0x080483d3 <+31>: add DWORD PTR [esp+0x1c],0x1
0x080483d8 <+36>: cmp DWORD PTR [esp+0x1c],0x9
0x080483dd <+41>: jle 0x80483c7 <main+19>
0x080483df <+43>: mov eax,0x0
0x080483e4 <+48>: leave
0x080483e5 <+49>: ret
now.. i understand every portion of this program, until it gets to:
0x080483ce <+26>: call 0x80482f0 <puts#plt>
what i do not understand is.. if "Hello, world\n" is stored at 0x80484b0, and that address is then stored into the address at ESP, why does the:
0x080483ce <+26>: call 0x80482f0 <puts#plt>
refer to 0x80482f0, instead of [esp] or just "0x80484b0" to print "Hello, world\n" to the screen? i used gdb and i cannot figure out what exactly is being referenced with 0x80482f0.. any help would be great
thanks (and remember, im just starting out with this stuff, so im a noob)
also.. i copy and pasted the disassembled main function from gdb for convenience, if you need any more info, just ask. and if you would like to explain that one command for me, that would be great as well because i've only used "int 80h"'s for printing stuff to the screen before
0x80482f0 is the address of the puts function. To be more precise, it points to the entry for puts() in the program linker table (PLT) - basically just a bunch of JMP <some routine in a so-library>s (it's a little more complex than that, but that's not important for this discussion). The puts function looks for its argument on the stack - ie, at [esp].
You may be wondering where that puts() call came from - the compiler here was smart enough to see that you didn't actually use any format string parameters in your call to printf(), and replaced that call with a call to the (somewhat faster) puts(). If you'll look closely, you'll see that it also removed the newline from your string, because puts() appends a newline after printing the string it is given.
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.