Scan hexadecimal floating points in Windows with Linux code - c

I am trying to compile Wapiti 1.3.0 (a NLP tagging tool) in a Windows 8 based machine. The C source code is intended for Linux (and similar) systems. I have managed to compile it using Cygwin gcc. Unfortunately it's not working as it needs to read data from a model file (text file where training information is saved).
It seems that the variable v is not being read, in this code line:
double v;
if (fscanf(file, "%"SCNu64"=%la\n", &f, &v) != 2)
I guess it is because the Cygwin dll's not being C99 and not being able to use the hex floating points.
I don't think I can compile it with MingW as it requires POSIX system headers, plus I am not sure if MingW handles C99 fscanf formatting anyway.
Is there any suggestion of what can I do, or am I missing something?
Thanks for your help!
The program is compiling/working in Linux no problems.

Related

Is it possible to modify a C program which is running?

i was wondering if it is possible to modify a piece of C program (or other binary) while it is running ?
I wrote this small C program :
#include <stdio.h>
#include <stdint.h>
static uint32_t gcui32_val_A = 0xAABBCCDD;
int main(int argc, char *argv[]) {
uint32_t ui32_val_B = 0;
uint32_t ui32_cpt = 0;
printf("\n\n Program SHOW\n\n");
while(1) {
if(gcui32_val_A != ui32_val_B) {
printf("Value[%d] of A : %x\n",ui32_cpt,gcui32_val_A);
ui32_val_B = gcui32_val_A;
ui32_cpt++;
}
}
return 0;
}
With a Hex editor i'm able to find "0xAABBCCDD" and modify it when the program is stopped. The modification works when I relauch the program. Cool !
I would like to do this when the program s running is it possible ?
Here is a simple example to understand the phenomena and play a little with it but my true project is bigger.
I have an old DOS game called Dangerous Dave.
I'm able to modify the tiles by simply editing the binary (thanks to http://www.shikadi.net/moddingwiki/Dangerous_Dave)
I developped a small editor that do this pretty well and had fun with it.
I launch the DOS game by using DOSBOX, it works !
I would like to do this dynamically when the game is running. Is it possible ?
PS : I work under Debian 64bit
regards
I was wondering if it is possible to modify a piece of C program (or other binary) while it is running ?
Not in standard (and portable) C11. Read the n1570 specification to check. Notice that most of the time in practice, it is not the C source program (made of several translation units) which is running, but an executable result of some compiler & linker.
However, on Linux (e.g. Debian/Sid/x86-64) you could use some of the following tricks (often with function pointers):
use plugins, so design your program to accept them and define conventions about your plugins. A plugin is a shared object ELF file (some *.so) containing position-independent code (so it should be compiled with specific options). You'll use dlopen(3) & dlsym(3) to do the dynamic loading of the plugin.
use some JIT-compiling library, like GCCJIT or LLVM or libjit or asmjit.
alter your virtual address space (not recommended) manually, using mprotect(2) and mmap(2); then you could overwrite something in a code segment (you really should not do that). This might be tricky (e.g. because of ASLR) and brittle.
perhaps use debug related facilities, either with ptrace(2) or by scripting or extending the gdb debugger.
I suggest to play a bit with /proc/ (see proc(5)) and try at least to run in some terminal the following commands
cat /proc/self/maps
cat /proc/$$/maps
ls /proc/$$/fd/
(and read enough things to understand their outputs) to understand a bit more what a process "is".
So overwriting your text segment (if you really need to do that) is possible, but perhaps more tricky than what you believe !
(do you mind working for several weeks or months simply to improve some old gaming experience?)
Read also about homoiconic programming languages (try Common Lisp with SBCL), about dynamic software updating, about persistence, about application checkpointing, and about operating systems (I recommend: Operating Systems: Three Easy Pieces & OsDev wiki)
I work under Debian 64bit
I suppose you have programming skills and do know C. Then you should read ALP or some newer Linux programming book (and of course look into intro(2) & syscalls(2) & intro(3) and other man pages etc...)
BTW, in your particular case, perhaps the "OS" is DOSBOX (acting as some virtual machine). You might use strace(1) on DOSBOX (or on other commands or processes), or study its source code.
You mention games in your question. If you want to code some, consider libraries like SDL, SFML, Qt, GTK+, ....
Yes you can modify piece of code while running in C. You got to have pointer to your program memory area, and compiled pieces of code that you want to change. Naturally this is considered to be a dangerous practice, with lot of restrictions, and with many possibilities for error. However, this was practice at olden times when the memory was precious.

Mingw compiling error on Linux with a program made on Windows

I've recently migrated from Windows 7 to Linux (Ubuntu 14.04) and want to compile a C program that I made. The program worked perfectly under Codeblocks 12.11 using GNU GCC compiler's basic settings. When compiling under linux under Codeblocks 13.12 using GNU GCC compiler's basic settings, I get the following error messages:
undefined reference to __mingw_vprintf
undefined reference to __chstk.ms
undefined reference to _fopen
... and so on with fscanf, malloc, etc...
I'm new to Linux and I am not used to C coding, or even programming in general. Does someone have an idea about what's going on?
you have three separate problem going on here.
(1) for _fopen, Microsoft has a nasty habit of renaming all the POSIX functions so they start with an underscore, while your Linux distribution is looking for the standard POSIX name, i.e. fopen. Welcome to the wonderfully frustrating world of cross-platform development :). On solution would be to add something along these lines:
#ifdef __WIN32
#define fopen _fopen
#endif
This in effect says, if compiling on a windows machine (which typically has __WIN32 defined as a preprocessor define; and if it is not you can always make sure that it is) replace every occurrence of fopen with _fopen. The preprocessor will do this for you.
(2) for __mingw_vprintf, I've never seen this function but from the name I would surmise that it is an implementation of vprintf specific to mingw. I personally would rewrite my code to stick with the standard C function vprintf. You can read the manual page for vprintf here; and the MSDN information can be found here. Again notice that many of the Microsoft provide functions have an underscore prepended to the name. You can do something like what you did in case (1) above.
N.B. Actually if I were to rewrite the program I would use C++ IO-streams, but I am sticking to a pure C answers.
(3) for __chstk.ms, again I've never seen this function. My suspicion is that it is something inserted into your code to perform stack checking to help prevent stack-based exploits. To the best of my knowledge there is no way you are going to get that to work on a Linux machine.

sscanf won't scan hexadecimal formatted float with "%a" under mingw

I am using gcc 4.6.1 with mingw in windows.
I recently learned about the %a format specifier for representing floats exactly in floating-point hex notation (in C99, apparently).
For some reason I can print a float this way just fine, but I am having trouble scanning it.
If I replace both instances of %a, with %f my code handles printing and scanning the the floating point number just fine.
The code seems to work just fine when I ran it on a traditional Unix system (gcc 4.2.1).
I have tried every variation I could think of with floats and doubles. I tried adding the flag -std=c99, which seemed to change whether it treated the numeric literal as a double or float, but it did not fix my problem.
I want to know 2 things, if anyone else can duplicate this problem, and what I might do to fix it.
#include <stdio.h>
int main(){
char buffer[1000];
sprintf(buffer, "%la", 21.3930);
double x = 0;
printf("\n");
printf(buffer);
if(!sscanf(buffer, "%la", &x))
printf("\nscan failed.");
printf("\n%la", x);
return 0;
}
The output is:
0x1.5649bap+4
scan failed.
0x0.000000p+0
Help would be greatly appreciated.
MinGW uses msvcrt.dll for the major part of its C runtime support. msvcrt.dll generally doesn't support C99 functionality.
There are some versions of MinGW that provide their own support for C99 I/O specifiers, but I haven't collected good information on exactly what versions support what C99 features.
See the following for some additional details:
https://stackoverflow.com/a/7136886/12711
https://stackoverflow.com/a/10680635/12711
Update: It looks like the TDM-64 distribution of MinGW (version 4.6.1) supports the C99 specifiers in the scanf() family of functions with prefixed names such as:
__mingw_sscanf()
__mingw_scanf()
It might be that support is improved in versions newer than 4.6.1 (it looks like that at least as of version 4.6.1 these functions are not in the 32-bit version of the TDM distribution - keep in mind that TDM-64 is capable of building 32-bit binaries as well as 64-bit binaries).
You can use a simple set of macros to 'redirect' the normal names to these functions.
Example output:
C:\temp>gcc --version
gcc (tdm64-1) 4.6.1
C:\temp>gcc -m32 -std=gnu99 -o test test.c
C:\temp>test
0xa.b24dd2f1a9fcp+1
0xa.b24dd2f1a9fcp+1

Where do i get BIOS.h file, to import in Mingw?

Mingw don't have BIOS.h file by default. And i'm doing system programming by using netbeans IDE and a third party tool mingw. . ?
Can any one helps me, where do i get that file?
This is the code.
#include<stdio.h>
#include<BIOS.H>
#include<DOS.H>
char st[80] ={"Hello World$"};
void main()
{
_DX = (unsigned int) st;
_AH = 0x09;
geninterrupt(0x21);
}
Nowhere, you don't.
Those header files (dos.h and bios.h) are from 16-bit DOS compilers such as Turbo C or Open Watcom C. MinGW is a 32-bit compiler for Windows. As such, even if you get these header files, they will be useless because:
they are incompatible with gcc
they also need counterpart libraries because the headers themselves do not contain definitions of things like geninterrupt()
DOS interrupt services (int 21h) are not available to Win32 programs
Further, gcc does not support variables aliasing to CPU registers (e.g. _DX, _AH).
You either need to use the appropriate 16-bit DOS compiler or write a Windows program using functionality available from gcc and Win32 API.
Do you really need it? It's been obsoleted a hundred or so times. But from what I've heard, some older Turbo C versions might have it. You can also try out http://www.sandroid.org/TurboC/ , but they say the file might not have all the functions.

AIX equivalent of ieee754.h

I wrote some C code that serializes certain values into a file that is subsequently deserialized (using custom code) in Java on another machine.
Among values I'm serializing are 64-bit double precision floating point real numbers. When I wrote the code, it was going to be compiled and run only on Linux with a gcc available to compile it. I used ieee754.h to get access to all parts of the value, as per IEEE 754 standard, and write those parts to a file. On Java end, I would simply use Double.longBitsToDouble(long) to reassemble the value.
The problem is that I've been asked to make the code able to compile and run on AIX 5.3, using xlc 10.
Is there any equivalent of ieee754.h on AIX?
Short of endianness issues, IEEE754 is a fixed format. There's no need for a system header to tell you what it looks like. Just do something like:
uint64_t rep;
double x;
memcpy(&rep, &x, sizeof rep);
You might want to include some code for conditionally byte-order-swapping the result if you're on a platform where you have to do that, but as far as I know, AIX is not going to be one of those.

Resources