Many 'printf' in ollydbg but only one 'printf' in a.exe - c

Here the concise c code:
#include <stdio.h>
int main()
{
printf("abcdefg\n");
return 0;
}
when I open it with ollydbg, and then type E (executable module), right click the a module and select 'view executable file'. it will show the below window:
However, when I ctrl + B search for the 'printf', I got three result (ctrl + L will find the next)
My question is:
In my code is only one 'printf' function, why can I find 3 'printf' in the ollydbg.

My guess is, when you include stdio.h it must contain more occurrences of printf string, compiled source is not only your source but also everything you include.
I don't think names of functions should be included in the binary file (but I'm not an expert), I think only reason they are there is you compile it with debugging options on. You can check it easily by compiling the binary without debugger on and checking the executable with some hex editor.
I recommend to study how compilers work?. The link I sent might be good place to start and study.

Related

how to call a function located in another file in C using external?

I'm using a book, and now I'm studying external variables. I'm supposed to use a function located in another file and return a value from that function. But I don't understand how does this happens exactly. This is the code provided by the book:
This is the code in the first file:
#include <stdio.h>
double getCircum(double);
double PI = 3.14;
int gi;
int main(void)
{
double r = 5.87;
const double PI = 3.14;
printf("%.f", getCircum(r));
}
This is the code in the other file:
external double PI;
double getCircum(double r)
{
return 2 * r * PI;
}
The output is supposed to be 36.88. but I keep getting an error message that the file is not the directory. I don't know what file it that. Also, I don't really get how the code is supposed to look for a function in a different file, is the code missing something?
This is possible through to the linking process.
When reading your C first file, the compiler will output an object file which contain unresolved references to symbols like printf, getCircum because they are declared (printf in <stdio.h> and getCircum in your first file) but not implemented (you didn't wrote them code in the first file).
When reading the second file, the compiler will miss the definition of PI.
This doesn't prevent him from producing valid object files. After removing the line double PI = 3.14 (it miss a ;), compile without linking with :
cc -c -o 1st_file.o 1st_file.c
cc -c -o 2nd_file.o 2nd_file.c
This will output two object files, if you run obj-dump -t 1st_file.o 2st_file.o you will see a list of provided and unresolved symbols of both files.
Now we will link with cc -o program.exe 1st_file.o 2nd_file.o. The C compiler will link both objects and some system-wide ones inside program.exe.
And voilà !
In your case cc -o program.exe 1st_file.c 2nd_file.c will do the job. But in real program, recompiling the whole program at each test take a lot of time, I have a private project which take 3,5 seconds to link vs 17,5 to recompile everything for 4k lines of code, Linux itself has more than a 2M lines of code...
Finally, post the console output and build command in the question, my answer make the important assumption that you are on a Linux with a working C compiler and GNU binutils, StackOverflow has a great doc here https://stackoverflow.com/help/how-to-ask to ask good question which have more chances to be solved
Edit: Defining PI 2 times here is not an error

Link with custom function instead of crt one

I'm working on an application which defines it's own printf() to get around differences between the different CRTs out there or because some other platforms don't have it.
When building the application with gcc this automatically seems to work and the custom printf is used instead of libc's one; if I understand it correctly this is because of the order in which object files/libraries appear in the link command or maybe because object files are always searched before CRT libs, correct?
I'd like to do the same using msvc. Just building the project gives the expected 'LNK2005: _printf already defined in printf.obj' because printf is also in msvcrtd.lib. Fair enough. I know about /NODEFAULTLIB but that excludes everything resulting in unresolved references for everything but printf. I scanned through the other linker settings but couldn't find anything which allows this (apart from /FORCE maybe, but the 'might produce an invalid executable' comment doesn't make it sound like a good idea). Also nothing in the module definition file docs; the latter got me thinking it might be possible to create a stub library which has all exports from msvcrt.lib except printf but that seems a brittle solution even if it works.
In the end the question is simple: how do I tell msvc's linker it should skip msvcrt's printf definition and use the one from my printf.obj instead. Basically /NODEFAULTFUNCTION:printf or so. Just an answer for one single executable is ok, though I'd also be interested to know if and how it can be done when building a dll instead where the custom printf is exported: how to tell the linker it should use the export from my .lib instead of msvcrt.lib?
edit simplest repo I could find: create a file main.c:
#include <stdio.h>
int main(int argc, char** argv)
{
printf("Hello");
return 0;
}
and a file printf.c:
int printf(const char *fmt, ...)
{
write(1, "ok\n", 3);
return 3;
}
For VS2013 (though the other versions might work as well): create a new empty C++ project and add both files then build. (For gcc: just gcc main.c printf.c and the resulting a.out prints 'ok')
The culptrit for VS is #include : without that it works ok but I have yet to find out if the original code allows getting rid of it in some way. But even if it does I'd still want to know if this can be solved at the link level.

multiple definition of main first defined here

I'm new to programming and currently I'm learning C programming. I'm writing codes on the code blocks and in it using GCC compiler. When I create a new project, (as you know it creates main.c file with it) and due to that I'm not able to compile another file in that project.
File 1:
#include<stdio.h>
int main()
{
int a,b,c,d;
printf("Enter three numbers\n");
scanf("%d%d%d",&a,&b,&c);
d=a;
if(b>d)
d=b;
if(c>d)
d=c;
printf("\n The maximum of three numbers is %d",d);
}
File 2: main.c
#include <stdio.h>
int main()
{
printf("Hello world!\n");
return 0;
}
When I compile the first programme, it shows the following error:
multiple definition of 'main'
first defined here
I've searched every where I could and I'm not able to solve this. In one of the answers here on stack overflow, someone had suggested to write this in
(Project->Build options...->Linker settings (tab))
-Wl,--allow-multiple-definition
When I wrote it, there were no errors. But it wasn't able to run my File 1 and instead, it runs that main.c file. Even when I close the main.c file, it opens there again and runs main.c file which gives the output "Hello World!".
Initially when I was using code blocks there were no such errors. I don't know why this is happening and I've not much knowledge about compilers.
As noted in comments you can only have one main function.
So when you start a new project you need to replace the main.c file with the main.c file you want to use. Or you can edit the 'hello world' main.c program.
When you start a new project in code::blocks you can get a new directory with a simple program that prints 'Hello World'. This file is usually main.c. You need to edit this file or replace it. The reason that code::blocks puts this simple main.c program in the new project is so that you can compile it and test your system without having to write a new program.
Some computer languages allow you to use the same function name for different functions ( which are identified by their parameters and sometimes return types ). That's called overloading. C does not allow this. Functions in C must have unique names.
The main() function is a special one in C as it is used as the standard entry point for applications. That is, the main() function will be called first and your application should start and (typically) end in that function.
As a beginner I would suggest you avoid automated editor features that create and build projects for you. You will miss out on learning how things work doing that. Use an editor to start from empty files and learn how they all connect and how to use the compiler from the command line. The command line is something every beginner should start from, IMO.
It may be harder to learn, but it will give you a much better feel for what is going on.
I guess what you maybe trying to do is have multiple sandbox "gists" that you may wanna run all as their own main function. If that is the case, then just close your project and open the files directly. As long as they are not in a project, they will run fine.

Scratchbox2 returns "Implicit declaration of function getline", among other weird behaviour

I'm trying to cross compile my application for the maemo environment (GNU).
When compiling the application normally, everything works fine, however when it's compiled through sb2 the following warning comes up:
$ sb2 gcc -D_GNU_SORCE -o app -Wall -g -I.......//don't think this is relevant
In file included from wifi_collector_menu.c:50:
wifi_collector_list.c: In function `show_net_apns':
wifi_collector_list.c:777: warning: implicit declaration of function `getline'
I am completely confused as to why this happens, there are other getlines that do work in the program, i have tried to define the variable _GNU_SOURCE both inside the code and in the compiler command (not at the same time)
This is the line of code which causes the warning apparently:
size_t bytesnum = MAX_ESSID;
size_t bytes_read;
char *netname = NULL;
printf("Enter name of selected network:");
bytes_read=getline(&netname,&bytesnum,stdin);//This line
Any help would be appreciated, thanks in advance.
Problem solved, all I had to do was add:
#define _GNU_SOURCE
In each header file, before stdio.h was included, very simple really.
I guess this info is assumed known between programmers as i was unable to find it anywhere online, and had to ask my C programming professor personally, and even then we had some trouble tracing the source.
Thanks anyway.
Change your compiler line to include the -E option and redirect the output. The compiler will only pre-proccess your file when this option is used. Do this for both versions, with and without sb2. getline() is normally found in stdio.h. By viewing the preprocessed output from both versions, you should be able to see where getline() is being included from.

problems with memset in Metal C

I’m trying to initialize the Metal C environment with the following code, but get the following errors on the memset line.
ERROR CCN3275 IMIJWS0.METAL.SAMPLIB(MEM):6 Unexpected text ')' encountered.
ERROR CCN3045 IMIJWS0.METAL.SAMPLIB(MEM):6 Undeclared identifier ___MEMSET.
ERROR CCN3277 IMIJWS0.METAL.SAMPLIB(MEM):6 Syntax error: possible missing ')' or ','?
CCN0793(I) Compilation failed for file //'IMIJWS0.METAL.SAMPLIB(MEM)'. Object file not created.
Below is my code
#include &lt string.h&gt
#include &lt stdlib.h&gt
#include &lt metal.h&gt
void mymtlfcn(void) {
struct __csysenv_s mysysenv;
memset ( &mysysenv, 0, sizeof ( mysysenv ) );
mysysenv.__cseversion = __CSE_VERSION_1;
mysysenv.__csesubpool = 129;
mysysenv.__cseheap31initsize = 131072;
mysysenv.__cseheap31incrsize = 8192;
mysysenv.__cseheap64initsize = 20;
mysysenv.__cseheap64incrsize = 1;
The issue was with the search order. Although I did search(/usr/metal/include) from with in my JCL I didn't proceed it with a nosearch option, so string.h was getting picked up from the standard system librarys instead of the version included with Metal C. I've pasted my optfile dataset I passed to the CPARM below for refference.
//OPTIONS DD *
SO
LIST
LONG
NOXREF
CSECT
METAL
LP64
NOSEARCH
search(/usr/include/metal/)
So, I have no idea. But some suggestions:
You might try copying/pasting this code here from this example just to make sure it works 'as expected'
Maybe try defining some of the macros here? (when I did C programming on zOS, I had to do include some weird macros in order to get stuff to work. I have no reasonable technical explanation for this.)
You could try searching for memset() using "=3.14" (from ispf.) See if any other modules use that function, and then check the headers that they include (or macros that they define - either in the C files or H files) to make it work.
Another thought: before the memset(), try doing putting a printf() in. If you get a syntax error on the same line (only for printf, rather than memset) then you can see if the problem is before line 6 - like a misplaced parenthesis.
Finally, if i recall correctly, I had to compile my individual modules, and then link them manually (unless I wrote a JCL to do this for me.) So you might have to link once to link with your other modules, and then link again against the C library. Not to be pedantic, but: you're fairly certain that you're doing all of the link passes?
I realize that's a lot of hoops to try and you've probably already read the manuals, but maybe there is something useful to try?
Also, and you probably already know this, but this site (for looking up error codes) is infinitely useful. (along with the above links for full-text-searching the manual)
Edit: this page also talks about "built-in functions" - you could try (as stated at the bottom of the page) "#undef memcpy" to use the non-built-in version?
Can you show us your compiler arguments? You need to make sure that you're not pulling in the standard C header files in addition to the metal C ones. Here's an example:
xlc -c -Wc,metal,longname,nosearch,'list(./)' -I. -I /usr/include/metal -I "//'SYS1.SIEAHDRV'" -S -qlanglvl=extended foo.c
as -mrent -mgoff -a=foo.list -o foo.o foo.s
ld -bac=1 -brent -S "//'SYS1.CSSLIB'" -o foo foo.o
Are you missing the closing brace '}' for the function? How about any missing semi-colon line terminators? When missing braces/semi-colons the z/OS C compiler throws some strange/misleading messages sometimes. I don't have it to try out, but I'm assuming Metal does as well.

Resources