Here's what my screen looks like when I hit "Local Windows Debugger", then click the breakpoint button. The point it goes to is.....
http://i.stack.imgur.com/yufiH.png
My asm file says:
.model small
.stack
.data
.code
_Func proc
mov ax, 1
leave
ret
_Func endp
end
And the cpp file:
extern "C" {
int Func();
}
int main(int argc, char** argv) {
Func();
return 0;
}
So I'm wondering, why does this code hit this weird breakpoint. It isn't in my code...
And yes, I know what "int 3" in assembly means, that isn't what I'm wondering about. It isn't my code but it doesn't let my code run...
.model small is for 16-bit-MSDOS, not for 32-bit-Windows (Win32). Try following code:
.model flat
.code
_Func proc
mov eax, 1
ret
_Func endp
end
Related
I'm using Visual Studio 2017 Community to build a test console C++ application. I need to include an assembly function into that project:
extern "C" void* __fastcall getBaseFS(void);
To include an asm file I right-clicked the project and went to "Build dependencies" -> "Build Customization" and checked "masm" in the list there.
I can then add an asm file by right-clicking my project -> Add New item -> and then add "asm_x64.asm" file where I write my x86-64 asm code:
.code
getBaseFS PROC
mov ecx, 0C0000100H ; IA32_FS_BASE
rdmsr
shl rdx, 32
or rax, rdx
ret
getBaseFS ENDP
END
This works in a 64-bit project.
The problem is that when I switch solution platform from x64 to x86:
my asm file needs to change. So in a sense I need to include a different "asm_x86.asm" file into compilation that is used only for x86 builds vs. x64 builds.
What's the best way to automate this switch?
OK, thanks to Michael Petch, I got it solved. Had to put both x64 and x86 code in one .asm file.
(There's another proposed option to deal with build configuration, but I prefer the method I'm showing here. I had a bad luck with those build configurations disappearing when solutions were moved from computer to computer.)
So, I'm not sure why using IFDEF RAX works, and Microsoft's own proposed ifndef X64 doesn't. But oh well. If anyone knows, please post a comment.
asm_code.asm file:
IFDEF RAX
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; x64 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; WinAPI to call
extrn Beep : proc
.data
align 8
beep_freq:
dq 700 ; hz
beep_dur:
dq 200 ; ms
str_from:
db "Hail from x64 asm", 0
.code
useless_sh_t_function__get_GS_a_string_and_beep PROC
; parameter = CHAR** for a string pointer
; return = value of GS register selector
mov rax, str_from
mov [rcx], rax
mov rdx, qword ptr [beep_dur]
mov rcx, qword ptr [beep_freq]
call Beep
mov rax, gs
ret
useless_sh_t_function__get_GS_a_string_and_beep ENDP
ELSE
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; x86 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.686p
.XMM
.model flat, C
.data
align 4
beep_freq dd 700 ; hz
beep_dur dd 200 ; ms
str_from db "Hail from x86 asm", 0
.code
; WinAPI to call
extrn stdcall Beep#8 : proc
useless_sh_t_function__get_GS_a_string_and_beep PROC
; parameter = CHAR** for a string pointer
; return = value of GS register selector
mov eax, [esp + 4]
mov [eax], OFFSET str_from
push dword ptr [beep_dur]
push dword ptr [beep_freq]
call Beep#8
mov eax, gs
ret
useless_sh_t_function__get_GS_a_string_and_beep ENDP
ENDIF
END
main.cpp file:
#include "stdafx.h"
#include <Windows.h>
extern "C" {
size_t useless_sh_t_function__get_GS_a_string_and_beep(const CHAR** ppString);
};
int main()
{
const char* pString = NULL;
size_t nGS = useless_sh_t_function__get_GS_a_string_and_beep(&pString);
printf("gs=0x%Ix, %s\n", nGS, pString);
return 0;
}
Good that you found a way to handle your use case.
However, if you have more asm files, or only need them for some build types, you could also change the settings for each individual file for the parts where it differs from the project defaults.
Just right-click a file name to get to its individual properties.
To have an asm file included in x64 builds only, you can use these settings:
And then exclude it from 32-bit builds:
These settings are available for all file type, not only for .asm files.
I have been searching around for a while, and couldn't seem to find the answer to my issue. I'm trying to code some functions to detect whether or not the executable is being debugged, and I'm using some inline assembly for it (with the __asm tag). It keeps throwing two errors, and the rest of the code seems to compile fine. Here's the function
int peb_detect() {
__asm {
ASSUME FS : NOTHING
MOV EAX, DWORD PTR FS : [18]
MOV EAX, DBYTE PTR DS : [EAX + 30]
MOVZX EAX, BYTE PTR DS : [EAX + 2]
RET
}
}
and I keep getting the errors
warning C4405: 'FS': identifier is reserved word
warning C2400: inline assembler syntax error in 'opcode'; found 'FS'
warning C2408: illegal type on PTR operator in 'second operand'
I can't seem to figure it out. If anyone can help, I would really appreciate it. Thanks!
at first not 18 but 0x18 and not 30 but 0x30
C_ASSERT(FIELD_OFFSET(NT_TIB, Self) == 0x18);
C_ASSERT(FIELD_OFFSET(TEB, ProcessEnvironmentBlock) == 0x30);
need use not hard coded constants. especially wrong.
at second int peb_detect() must be __declspec(naked) if you use RET instruction. so code can look like this:
#include <winternl.h>
#include <intrin.h>
__declspec(naked) BOOLEAN peb_detect() {
__asm {
MOV EAX, FS:[NT_TIB.Self]
MOV EAX, [EAX + TEB.ProcessEnvironmentBlock]
MOV AL, [EAX + PEB.BeingDebugged]
RET
}
}
but we can use and shorter variant
__declspec(naked) BOOLEAN peb_detect2() {
__asm {
MOV EAX, FS:[TEB.ProcessEnvironmentBlock]
MOV AL, [EAX]PEB.BeingDebugged
RET
}
}
and for implement IsDebuggerPresent we can not use inline assembler at all. and this will be work for x64 too
__forceinline BOOLEAN peb_detect3()
{
return ((PEB*)
#ifdef _WIN64
__readgsqword
#else
__readfsdword
#endif
(FIELD_OFFSET(_TEB, ProcessEnvironmentBlock)))->BeingDebugged;
}
I'm trying to convert an inline asm code form VS to GCC (AT&T).. the original code is this one:
char mystr[] = "Hello world";
_asm mov eax,0
_asm lea ebx, [mystr]
Here is my attempt to convert that code in gcc at&t syntax:
char mystr[] = "Hello world";
asm("mov $0,%%eax\n"
"leal (%0),%%ebx\n"
: : "r"(mystr));
This code doesn't seems to work, any idea why ?
Thank you very much
This code seems to works:
char* mystr = "Hello world";
asm("mov $0,%%eax\n"
"leal (%0),%%ebx"
::"b"(mystr));
I've changed char mystr[] to char* mystr, and "r" with "b"..
If somebody know what "b" does exactly, please let me know...
many thanks
I am attempting to debug a program (.exe) written in C++. The program is a console application, and is mathematical-oriented simulation, no GUI or interface code. I am attempting to start a debug session on this program compiled in Visual Studio 2008 on Win 7 (64 bit), by right-clicking the executable from VS's solution explorer and selection "step into new instance". However, before the very first line of code is executed, Visual Studio reports "Unhandled exception at 0x00000001401b3937 in sim.exe: 0xC00000FD: Stack overflow." Here's a snippet of the first couple lines of code
int_T main(int_T argc, const char_T *argv[])
{
SimData thisSim;
int InputFlag = 0;
The debugger arrow is pointing at the first angle bracket.
Here's a snapshot of the dissabembly view:
int_T main(int_T argc, const char_T *argv[])
{
0000000140141930 mov qword ptr [rsp+10h],rdx
0000000140141935 mov dword ptr [rsp+8],ecx
0000000140141939 push rsi
000000014014193A push rdi
000000014014193B mov eax,1120C8h
0000000140141940 call __chkstk (1401B3900h)
0000000140141945 sub rsp,rax <------DEBUGGER IS STOPPED HERE
0000000140141948 mov rax,qword ptr [__security_cookie (1401F7050h)]
000000014014194F xor rax,rsp
0000000140141952 mov qword ptr [rsp+1120B0h],rax
///////////////////////////////////////////////////////////////////////////
/* Initialize Instance of SimData */
SimData thisSim;
int InputFlag = 0;
000000014014195A mov dword ptr [rsp+20h],0
I'm not a Visual Studio expert, but I have used it a fair amount to do debugging in the past, and I've never seen this behavior.
Any thoughts on how to proceed?
Why does the following macro compile with 1 inline assembly instruction but not with 2?
This code compiles OK:
#define foo(x,output,ctx) {\
__asm\
{\
mov eax, 0xCAFEBEE1\
}\
}
but this code produces an error:
#define foo(x,output,ctx) {\
__asm\
{\
mov eax, 0xCAFEBEE1\
add eax, 5\
}\
}
Try this:
#define foo(x,output,ctx) {\
__asm mov eax, 0xCAFEBEE1 \
__asm add eax, 5\
}
Whenever you have a problem with the pre-processor, be sure to use Project + Properties, C/C++, Preprocessor, Preprocess to a file = Yes. Build and you'll find a .i file in the build directory. Which shows this on your snippet:
int wmain(int argc, _TCHAR* argv[])
{
{ __asm { mov eax, 0xCAFEBEE1 add eax, 5 }};
return 0;
}
Now it is obvious, there are no line endings on the macro lines. Curse at the preprocessor a bit to make you feel better. Then one __asm per line to fix.