Does WINE implement "_printf" and similar functions in MSVCRT? - wine

Here is an example program that illustrates my problem, it can be compiled using FlatAssembler without using a linker:
format PE console
entry start
include 'win32a.inc'
section '.text' code executable
start:
mov dword [esp],_output1
call [printf]
mov dword [esp+4],first
mov dword [esp],_input
call [scanf]
mov dword [esp],_output2
call [printf]
mov dword [esp+4],second
mov dword [esp],_input
call [scanf]
finit
fld dword [first]
fabs
fld dword [second]
fxch
fld1
fxch
fyl2x
fldl2e
fdivp st1,st0
fmulp st1,st0
fldl2e
fmulp st1,st0
fld1
fscale
fxch
fld1
fxch
fprem
f2xm1
faddp st1,st0
fmulp st1,st0
fstp dword [result]
fld dword [result]
fst qword [esp+4]
mov dword [esp],_output
call [printf]
invoke system,_pause
invoke exit,0
_output1 db "Enter the first number: ",0
_output2 db "Enter the second number: ",0
_input db "%f",0
_pause db "PAUSE",0
_output db "The first number to the power of the second number is: %f.",10,0
section '.rdata' readable writable
result dd ?
first dd ?
second dd ?
section '.idata' data readable import
library msvcrt,'msvcrt.dll'
import msvcrt,printf,'printf',system,'system',exit,'exit',scanf,'scanf'
So, the expected output is, of course, something like this:
Enter the first number: -2.5
Enter the second number: -2
The first number to the power of the second number is: 0.16
And that's the output I indeed get if I run that program on Windows 10. However, if I try to run that program on WINE on Oracle Linux, the output I get is:
000f:fixme:service:scmdatabase_autostart_services Auto-start service L"MountMgr" failed to start: 2
000f:fixme:service:scmdatabase_autostart_services Auto-start service L"WineBus" failed to start: 2
wine: Bad EXE format for Z:\home\teo.samarzija\Documents\Assembly\debug.exe.
Any idea what's going on?
I've done a little research, and I can't find any reference confirming that _printf and _scanf are even implemented in WINE's MSVCRT. However, I am not sure that's the problem, and, if it is a problem, that that's the only problem.

However, if I try to run that program on WINE on Oracle Linux, the
output I get is:
000f:fixme:service:scmdatabase_autostart_services Auto-start service L"MountMgr" failed to start: 2
000f:fixme:service:scmdatabase_autostart_services Auto-start service L"WineBus" failed to start: 2
wine: Bad EXE format for Z:\home\teo.samarzija\Documents\Assembly\debug.exe.
A "Bad EXE format" error is something different entirely. It doesn't imply that the problem is a missing imported function. The loader never got that far. It wasn't even able to read your binary. This is very likely caused by a bitness mismatch. For example, trying to run a 64-bit application on a 32-bit system.
Aside from this problem, it is worth pointing out that your attempted use of C runtime library functions is inherently non-portable. It might work, if Wine (or whatever other runtime environment) provides a function with an identical signature, but it very likely won't.
I suppose I should further clarify, since calling a standard C runtime library function "non-portable" may raise a few eyebrows. These functions are portable at the source-code level, but not at the binary level. Even without the added complexity of Wine, the C runtime library functions are non-portable, as Microsoft's CRT is versioned—you have to link to the appropriate version and have that DLL available at runtime, or your application will not work.
This exact problem is why Windows provides wrappers for these standard functions as part of the basic platform API, which is universally available. If you want to be fully portable to all implementations of the Win32 environment, and you aren't linking in your own copy of the C runtime library, then you should call these functions instead.
The Win32 version of the sprintf function is wsprintf. It has the same interface as sprintf, so you can call it the same way, as a drop-in replacement. In fact, although you shouldn't rely on this, it is implemented by Windows as a simple wrapper around the sprintf version provided by the local copy of the C runtime libraries.
If you want a version to which you can pass an argument list (a la vsprintf), then you can call wvsprintf.
Note that, unlike most of the Windows API functions, these functions use the __cdecl calling convention, not the __stdcall calling convention. Make sure that you are adhering to that in your assembly code. In short, that means passing arguments from right-to-left and cleaning up the stack at the call site.
Microsoft has, however, deprecated these functions, as they aren't entirely safe (buffer overflows and etc. are possible). As replacements, they offer the functions in the StrSafe.h header. These functions come in two variants: those which take a count of bytes (Cb) and those which take a count of characters (Cch). The relevant ones to this discussion would be either StringCbPrintfA or StringCchPrintfA. These are trickier to use from assembly language, however, because they're meant to be used inline by simply including the StrSafe.h header file. You can use them in library form, but then you'll need to pass the corresponding StrSafe.lib stubs to the linker. Note that linking to this library means your application will only run on Windows XP with SP2 or later.
This gets you halfway there. You are actually trying to call printf, rather than sprintf. The gap, of course, is getting the formatted string written to the console. Once you have the formatted string (generated by wsprintf, StringCchPrintfA, or whatever), that can be accomplished by calling the WriteConsole function, which is the Win32 API for writing output to the console window. If you want STDOUT, then you need to open that handle first with GetStdHandle(STD_OUTPUT_HANDLE).

Anyway, I got the answer:
https://www.linuxquestions.org/questions/linux-general-1/can%27t-install-wine-on-64-bit-oracle-linux-4175655895/page2.html#post6012838
In short, on 64-bit Oracle Linux, WINE needs to be compiled from source to work properly.

Related

nasm: ELF format cannot produce non-PC-relative PLT references

I'm experiencing an error with nasm compiler. Inside nasm's source code the error originates here.
I' trying to build an relocatable object file that can resolve a specific symbol during run time linkage (not build time linkage).
Minimal code:
EXTERN start
foo:
; wrt: with respect to
dd start wrt ..plt
The error is ELF format cannot produce non-PC-relative PLT references.
What's going on here?
It seems like you have to use dd start wrt ..got, i.e. reference the global offset table instead of the procedure linkage table. The latter would only work with something like call start wrt ..plt, i.e. an real instruction. In this case you are using dd, i.e. storing an immediate value in the output.

Hooking syscalls in Go

I'm trying to hook the fopen syscall in linux using Go.
Normally I would use C for something like this (Example: https://stackoverflow.com/a/880278/5572976) but the CTF states that the solution needs to be written in Go.
I've looked at the syscall package and basically what I'm looking for is using the following in Go.
dlsym(RTLD_NEXT, "open");
EDIT: That's open, not fopen.
try this Runtime dynamic library loader (dlopen / dlsym) for Go (golang)

ASM to push function arguments to the stack

I'm trying to port a program to x64 using vs2008. The problem is, however, that the is some inline asm code that is not supported on x64. This asm code is used to push arguments with unknown type or number to functions from dll. It is an interpeter based program in which you can specify a function to use from a certain dll and the program pushes the arguments and calles the function at compile time.
Using various sources I've concluded that generating seperate .asm files that contain asm functions which can be compiled unsing masm and their obj files linked to vs2008. Using different files for x86 and x64 the program builds for both problems. The problem is however, that the functions do not replicate what the inline asm is doing.
I converted the following inline code, for example:
double a = Evaluate(arg[i]).num;
_asm push a + 4
_asm push a
j += 8;
To:
double a = Evaluate(arg[i]).num;
EvaluateFuncArgFloat(a);
j += 8;
With the follwoing .asm file:
TITLE EvaluateFuncArgFloat (evaluate_asm.asm)
.386
.model flat, C
.code
EvaluateFuncArgFloat PROC a:DWORD
push a + 4
push a
ret
EvaluateFuncArgFloat ENDP
END
This does not do what I'm expecting. The double simply does not end up in the function as it did when using inline asm.
My guess is that there is a small error or something I've left out, but after many tries I can't seem to get it to work. Hopefully someone can help me with this problem, it is very much appriciated.
A sneaky way to do this could be
EvaluateFuncArgFloat PROC a:DWORD
pop eax ;ret address popped to a safe register (if not ax/eax)
push a + 4
push a
push eax ;ret address back at top of stack
ret
EvaluateFuncArgFloat ENDP
The problem is you've pushed 2 numbers onto the stack and not removed them a+4 and a
Presumably another part of your original code deals with this in the original program

How to put assembly markers to C++ code (x64)

I need to put markers to C++ code that should be visible in assembly or binary. It seems it’s straight forward to do it for 32 using inline assembly:
__asm {
NOP
NOP
NOP
}
or using DB assembly statement:
__asm {
DB 0x00, 0xFF, 0x10
}
But VisualStudio 2005 and better does not support inline assembly for x64. Is there any way to do it? Probably I can make a function in separate assembly module but how I can be sure that linker will put an actual assembly there instead of CALL?
Define a global volatile variable somewhere, say volatile __int64 blah = 0;. Then wherever you want some marker, use _InterlockedCompareExchange64(&blah, SOME_UNIQUE_CONSTANT1, SOME_UNIQUE_CONSTANT2);. You'll be guaranteed to find instructions loading ECX:EBX with SOME_UNIQUE_CONSTANT1 and EDX:EAX with SOME_UNIQUE_CONSTANT2 followed by LOCK CMPXCHG8B (0xF0, 0x0F, 0xC7, etc -- see instruction encoding details).
The MSDN says you can use intrinsic functions.
//MyAsmCode.asm
.code
MyFunction proc
...
MyFunction endp
end
compile it (ml64.exe).
You get object file (MS COFF 64): MyAsmCode.obj
In VS add MyAsmCode.obj to linker additional dep.
Now you can call this function. ;)

How to embed version information into shared library and binary?

On Linux, is there a way to embed version information into an ELF binary? I would like to embed this info at compile time so it can then be extract it using a script later. A hackish way would be to plant something that can be extracted using the strings command. Is there a more conventional method, similar to how Visual Studio plant version info for Windows DLLs (note version tab in DLL properties)?
One way to do it if using cvs or subversion is to have a special id string formatted specially in your source file. Then add a pre-commit hook to cvs or svn that updates that special variable with the new version of the file when a change is committed. Then, when the binary is built, you can use ident to extract that indformation. For example:
Add something like this to your cpp file:
static char fileid[] = "$Id: fname.cc,v 1.124 2010/07/21 06:38:45 author Exp $";
And running ident (which you can find by installing rcs) on the program should show the info about the files that have an id string in them.
ident program
program:
$Id: fname.cc,v 1.124 2010/07/21 06:38:45 author Exp $
Note As people have mentioned in the comments this technique is archaic. Having the source control system automatically change your source code is ugly and the fact that source control has improved since the days when cvs was the only option means that you can find a better way to achieve the same goals.
To extend the #sashang answer, while avoiding the "$Id:$" issues mentioned by #cdunn2001, ...
You can add a file "version_info.h" to your project that has only:
#define VERSION_MAJOR "1"
#define VERSION_MINOR "0"
#define VERSION_PATCH "0"
#define VERSION_BUILD "0"
And in your main.c file have the line:
static char version[] = VERSION_MAJOR "." VERSION_MINOR "." VERSION_PATCH "." VERSION_BUILD;
static char timestamp[] = __DATE__ " " __TIME__;
(or however you want to use these values in your program)
Then set up a pre-build step which reads the version_info.h file, bumps the numbers appropriately, and writes it back out again. A daily build would just bump the VERSION_BUILD number, while a more serious release would bump other numbers.
If your makefile lists this on your object's prerequisite list, then the build will recompile what it needs to.
The Intel Fortran and C++ compilers can certainly do this, use the -sox option. So, yes there is a way. I don't know of any widespread convention for embedding such information in a binary and I generally use Emacs in hexl-mode for reading the embedded information, which is quite hackish.
'-sox' also embeds the compiler options used to build an executable, which is very useful.
If you declare a variable called program_version or similar you can find out at which address the variable is stored at and then proceed to extract its value. E.g.
objdump -t --demangle /tmp/libtest.so | grep program_version
0000000000600a24 g O .data 0000000000000004 program_version
tells me that program_version resides at address 0000000000600a24 and is of size 4. Then just read the value at that address in the file.
Or you could just write a simple program that links the library in questions and prints the version, defined either as an exported variable or a function.

Resources