Basing on that code I found on google (which is working fine on GCC compiler)
#define ASM __asm__ __volatile__
void MyFunc()
{
ASM("enc_start:\n\t");
printf("Hello, world!");
ASM("enc_end:\n\t");
}
int main()
{
unsigned int addr, len;
ASM("movl $enc_start, %0\n\t"
"movl $enc_end, %1\n\t"
: "=r"(addr), "=r"(len));
printf("Address of begin of function: %X", addr);
printf("Len is of: %d bytes", len);
return 0;
}
I would like to convert it in visual studio, I tried but I failed. I don't even know if that's possible. Can you please convert it for me or at least giving me a similar way for get the same result ?
Thanks a lot.
Visual Studio's inline assembly doesn't support labels IIRC, and without them, the whole snippet is useless. What are you trying to accomplish in the first place?
You can capture the current value of EIP in VS's inline assembly as the function is executing, but not externally.
By the way, even in GCC, it won't capture the address and length of the entire function's body. It'll capture address and length of the function sans the prologue and the epilogue code. To get function's real range, generate the MAP file and parse it.
I vaguely recall Visual Studio has prologue/epilogue size as predefined macros. I might be mistaken on this one.
You could try using a pointer to function to get the starting address of a function, but in the case of Visual Studio, in debug mode, it's a pointer to a branch instruction (part of a branch table) that branches to the function. This would require that you check to see if the pointer points to a branch instruction and if so, decode the branch instruction to determine the start of the actual function.
Related
I have two empty functions called TestFunc and TestFunc2, and I assigned their addresses to two variables.
void TestFunc()
{
}
__declspec(naked) void TestFunc2()
{
}
int main()
{
DWORD* test = (DWORD*)TestFunc;
DWORD* test2 = (DWORD*)TestFunc2;
printf("TestFunc is %p at test is %p\n", TestFunc, test);
printf("TestFunc2 is %p at test2 is %p\n", TestFunc2, test2);
getchar();
}
After assignment, the value of the two variables actually differ from what they are assigned.
However, in a printf statement, the output shows that they are the same. Any ideas why is this happening?
This is caused by incremental linking in Visual Studio, from this page you can learn that one of the drawbacks of this is:
An incrementally linked program is functionally equivalent to a program that is non-incrementally linked. However, because it is prepared for subsequent incremental links, an incrementally linked executable, static library, or dynamic-link library file:
Is larger than a non-incrementally linked program because of padding of code and data. Padding enables the linker to increase the size of functions and data without recreating the file.
May contain jump thunks to handle relocation of functions to new addresses.
and those jump thunks is what your have observed.
if you disable this option (vs2015):
Linker -> All Options -> Enable Incremental Linking to NO
then your addresses will be equal.
If you look closer in disassembly what is at the address which you have assigned to DWORD*, you will find that there is a jump to your function:
TestFunc:
000000014001117C jmp TestFunc (01400116D0h)
It has to do with the platform specific runtime environment your code is compiled to. C++ allows the runtime to do some pointer arithmetics behind the scene. It is dangerous to write any code that relies on this runtime behaviour.
If you really want to know, take a look at the assembler code at the memory. My guess would be that the runtime uses an extra jump table perhaps for the new edit and continue debug functionality that is improved/changed with each release of visual studio.
While debugging some crash, I've come across some code which simplifies down to the following case:
#include <cmath>
#pragma intrinsic (sqrt)
class MyClass
{
public:
MyClass() { m[0] = 0; }
double& x() { return m[0]; }
private:
double m[1];
};
void function()
{
MyClass obj;
obj.x() = -sqrt(2.0);
}
int main()
{
function();
return 0;
}
When built in Debug|Win32 with VS2012 (Pro Version 11.0.61030.00 Update 4, and Express for Windows Desktop Version 11.0.61030.00 Update 4), the code triggers run-time check errors at the end of the function execution, which show up as either (in a random fashion):
Run-Time Check Failure #2 - Stack around the variable 'obj' was corrupted.
or
A buffer overrun has occurred in Test.exe which has corrupted the program's internal state. Press Break to debug the program or Continue to terminate the program.
I understand that this usually means some sort of buffer overrun/underrun for objects on the stack. Perhaps I'm overlooking something, but I can't see anywhere in this C++ code where such a buffer overrun could occur. After playing around with various tweaks to the code and stepping through the generated assembly code of the function (see "details" section below), I'd be tempted to say it looks like a bug in Visual Studio 2012, but perhaps I'm just in too deep and missing something.
Are there intrinsic function usage requirements or other C++ standard requirements that this code does not meet, which could explain this behaviour?
If not, is disabling function intrinsic the only way to obtain correct run-time check behaviour (other than workaround such as 0-sqrt noted below which could easily get lost)?
The details
Playing around the code, I've noted that the run-time check errors go away when I disable the sqrt intrinsic by commenting out the #pragma line.
Otherwise with the sqrt intrinsic pragma (or the /Oi compiler option) :
Using a setter such as obj.setx(double x) { m[0] = x; }, not surprisingly also generates the run-time check errors.
Replacing obj.x() = -sqrt(2.0) with obj.x() = +sqrt(2.0) or obj.x() = 0.0-sqrt(2.0) to my surprise does not generate the run-time check errors.
Similarly replacing obj.x() = -sqrt(2.0) with obj.x() = -1.4142135623730951; does not generate the run-time check error.
Replacing the member double m[1]; with double m; (along with m[0] accesses) only seem to generate the "Run-Time Check Failure #2" error (even with obj.x() = -sqrt(2.0)), and sometimes runs fine.
Declaring obj as a static instance, or allocating it on the heap does not generate the run-time check errors.
Setting compiler warnings to level 4 does not produce any warnings.
Compiling the same code with VS2005 Pro or VS2010 Express does not generate the run-time check errors.
For what it's worth, I've noted the problem on a Windows 7 (with Intel Xeon CPU) and a Windows 8.1 machine (with Intel Core i7 CPU).
Then I went on to look at the generated assembly code. For the purpose of illustration, I will refer to "the failing version" as the one obtained from the code provided above, whereas I've generated a "working version" by simply commenting the #pragma intrinsic (sqrt) line. A side-by-side diff view of the resulting generated assembly code is shown below with the "failing version" on the left, and the "working version" on the right:
First I've noted that the _RTC_CheckStackVars call is responsible for the "Run-Time Check Failure #2" errors and checks in particular whenever the magic cookies 0xCCCCCCCC are still intact around the obj object on the stack (which happens to be starting at an offset of -20 bytes relative to the original value of ESP). In the following screenshots, I've highlighted the object location in green and the magic cookie location in red. At the start of the function in the "working version" this is what it looks like:
then later right before the call to _RTC_CheckStackVars:
Now in the "failing version", the preamble include an additional (line 3415)
and esp,0FFFFFFF8h
which essentially makes obj aligned on a 8 byte boundary. Specifically, whenever the function is called with an initial value of ESP that ends with a 0 or 8 nibble, the obj is stored starting at an offset of -24 bytes relative to the initial value of ESP.
The problem is that the _RTC_CheckStackVars still looks for those 0xCCCCCCCC magic cookies at those same locations relative to the original ESP value as in the "working version" depicted above (ie. offsets of -24 and -12 bytes). In this case, obj's first 4 bytes actually overlaps one of the magic cookie location. This is shown in the screenshots below at the start of the "failing version":
then later right before the call to _RTC_CheckStackVars:
We can note in passing the the actual data which corresponds to obj.m[0] is identical between the "working version" and the "failing version" ("cd 3b 7f 66 9e a0 f6 bf", or the expected value of -1.4142135623730951 when interpreted as a double).
Incidentally, the _RTC_CheckStackVars checks actually passes whenever the initial value of ESP ends with a 4 or C nibble (in which case obj starts at a -20 bytes offset, just like in the "working version").
After the _RTC_CheckStackVars checks complete (assuming it passes), there is an additional check that the restored value of ESP corresponds to the original value. This check, when it fails, is responsible for the "A buffer overrun has occurred in ..." message.
In the "working version", the original ESP is copied to EBP early in the preamble (line 3415) and it's this value which is used to compute the checksum by xoring with a ___security_cookie (line 3425). In the "failing version", the checksum computation is based on ESP (line 3425) after ESP has been decremented by 12 while pushing some registers (lines 3417-3419), but the corresponding check with the restored ESP is done at the same point where those registers have been restored.
So, in short and unless I didn't get this right, it looks like the "working version" follows standard textbook and tutorials on stack handling, whereas the "failing version" messes up the run-time checks.
P.S.: "Debug build" refers to the standard set of compiler options of the "Debug" config from the "Win32 Console Application" new project template.
As pointed out by Hans in comments, the issue can no longer be reproduced with the Visual Studio 2013.
Similarly, the official answer on Microsoft connect bug report is:
we are unable to reproduce it with VS2013 Update 4 RTM. The product team itself no longer directly accepting feedback for Microsoft Visual Studio 2012 and earlier products. You can get support for issues with Visual Studio 2012 and earlier by visiting one of the resources in the link below:
http://www.visualstudio.com/support/support-overview-vs
So, given that the problem is triggered only on VS2012 with function intrinsics (/Oi compiler option), runtime-checks (either /RTCs or /RTC1 compiler option) and usage of unary minus operator, getting rid of any one (or more) of those conditions should work around the problem.
Thus, it seems the available options are:
Upgrade to the latest Visual Studio (if your project permits)
Disable runtime checks for the affected functions by surrounding them with #pragma runtime_check such as in the following sample:
#pragma runtime_check ("s", off)
void function()
{
MyClass obj;
obj.x() = -sqrt(2.0);
}
#pragma runtime_check ("s", restore)
Disable intrinsics by removing the #pragma intrinsics (sqrt) line, and adding #pragma function (sqrt) (see msdn for more info).
If intrinsics have been activated for all files through the "Enable Intrinsic Functions" project property (/Oi compiler option), you would need to deactivate that project property. You can then enable intrinsics on a piece-by-piece basis for specific functions while checking that they are not affected by the bug (with #pragma intrinsics directives for each required intrinsic function).
Tweak the code using workarounds such as 0-sqrt(2.0), -1*sqrt(2.0) (which remove the unary minus operator) in an attempt to fool the compiler into using a different code generation path. Note that this is very likely to break with seemingly minor code changes.
I am proxying a method call in using a naked function and inline assembler.
__declspec(naked) void ProxyFunction()
{
static const unsigned int addressofRealFunction = 0x0041b200;
__asm
{
jmp [addressofRealFunction];
}
}
How can I translate this to x64? In visual studio there is no inline assembler or naked functions for x64.
Naked removes the assembly prologue and epilogue. I need this to make sure the stack frame stays equivalent for the call.
What would you do?
Try compiling it straight:
void ProxyFunction()
{
RealFunction();
}
See if the compiler optimizes it down to bare jump. It might.
If Microsoft's advise to use masm for tasks like this does not work for you, then one way is to look into allocating a page, set the executable attribute on it, then place the opcodes there using direct memory writes at an offset starting at the beginning of the page.
I am trying to use Assembly in C++ (Dev-CPP) and it won't output the string as it should. after some research I have discovered that it uses the AT&T syntax. my code will not output the string it just comes up with assembly messages.
This is my code:
#include <iostream>
using namespace std;
int main()
{
asm(".section .data");
asm("hello: .string\"Hello, World!$\"\n");
asm(".section .text");
asm("movl $0x09, %ah \n");
asm("mov hello, %dx\n");
asm("int 0x21");
system("PAUSE");
return 0;
}
could I get some help please.
In theory, only programs compiled with DJGPP (gcc port for DOS) can legally use DOS service functions via a DOS extender IFF you run them in DOS or Windows (XP and below, generally not Vista/7/8). Also, gcc does not generate 16-bit x86 code, which is what you seem to be expecting.
Further, you should really, really learn some inline assembly (google it up).
A compilable version if your code would look like:
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
asm(".section .data");
asm("hello: .string\"Hello, World!$\"\n");
asm(".section .text");
asm("movb $0x09, %ah\n"); // movl->movb
asm("movl $hello, %edx\n"); // mov->movl,hello->$hello,dx->edx
asm("int $0x21"); // 0x21->$0x21
system("PAUSE");
return 0;
}
But it's still unlikely to be good inline assembly because:
Your code trashes the registers and doesn't tell the compiler which are trashed, and so it likely corrupts the state of the program, which can lead to a crash or hang.
You write your instructions in individual asm statements, between which the compiler can insert any kind of code and disrupt your inline assembly. You really want to put your related instructions into a single block to prevent that from happening.
Something like this would be better:
asm volatile (
".section .data\n"
"hello: .string \"Hello, World!$\"\n"
".section .text\n"
"movb $0x09, %ah\n"
"movl $hello, %edx\n"
"int $0x21\n"
);
Unfortunately, this still won't work even with DJGPP. The problem has something to do with the memory segmentation setup done by DJGPP and the DPMI host (CWSDPMI), probably virtual memory. I can't tell what exactly is wrong there, but the above code doesn't work as-is.
So, please figure out what OS you're compiling your program for and write inline assembly code appropriately for that OS, that is, using correct registers and system call mechanisms.
DOS int 21h functions won't work in native Windows and Linux apps. Period. You've got the wrong tutorial.
To extend on Alexey's answer (how to overcome the segmentation issues), this would compile (and possibly run on DOS):
asm volatile(
"call 0f\n"
".byte 'H','e','l','l','o','W','o','r','l','d','!',0\n"
"0: pop %0\n"
"push %ds\n"
"push %cs\n"
"pop %ds\n"
"int $0x21\n"
"pop %ds\n" : "d"(0), "a"(9) : : "memory", "cc");
The idea is to inline the string within the code but jump over it; the return address of that call is the start address of the string. Then temporarily make the data segment identical to the code segment, call the DOS INT and restore the proper data segment after that.
In my ongoing experimentation with GCC inline assembly, I've run into a new problem regarding labels and inlined code.
Consider the following simple jump:
__asm__
(
"jmp out;"
"out:;"
:
:
);
This does nothing except jump to the out label. As is, this code compiles fine. But if you place it inside a function, and then compile with optimization flags, the compiler complains: "Error: symbol 'out' is already defined".
What seems to be happening is that the compiler is repeating this assembly code every time it inlines the function. This causes the label out to get duplicated, leading to multiple out labels.
So, how do I work around this? Is it really not possible to use labels in inline assembly? This tutorial on GCC inline assembly mentions that:
Thus, you can make put your assembly
into CPP macros, and inline C
functions, so anyone can use it in as
any C function/macro. Inline functions
resemble macros very much, but are
sometimes cleaner to use. Beware that
in all those cases, code will be
duplicated, so only local labels (of
1: style) should be defined in that
asm code.
I tried to find more information about these "local labels", but can't seem to find anything relating to inline assembly. It looks like the tutorial is saying that a local label is a number followed by a colon, (like 1:), so I tried using a label like that. Interestingly, the code compiled, but at run time it simply triggered a Segmentation Fault. Hmm...
So any suggestions, hints, answers...?
A declaration of a local label is indeed a number followed by a colon. But a reference to a local label needs a suffix of f or b, depending on whether you want to look forwards or backwards - i.e. 1f refers to the next 1: label in the forwards direction.
So declaring the label as 1: is correct; but to reference it, you need to say jmp 1f (because you are jumping forwards in this case).
Well, this question isn't getting any younger, but there are two other interesting solutions.
1) This example uses %=. %= in an assembler template is replaced with a number that is "unique to each insn in the entire compilation. This is useful for making local labels that are referred to more than once in a given insn." Note that to use %=, you (apparently) must have at least one input (although you probably don't have to actually use it).
int a = 3;
asm (
"test %0\n\t"
"jnz to_here%=\n\t"
"jz to_there%=\n\t"
"to_here%=:\n\t"
"to_there%=:"
::"r" (a));
This outputs:
test %eax
jnz to_here14
jz to_there14
to_here14:
to_there14:
Alternately, you can use the asm goto (Added in v4.5 I think). This actually lets you jump to c labels instead of just asm labels:
asm goto ("jmp %l0\n"
: /* no output */
: /* no input */
: /* no clobber */
: gofurther);
printf("Didn't jump\n");
// c label:
gofurther:
printf("Jumped\n");