How to relocate the bfd size symbols? - ld

When embedding binary files in a elf image with gcc, is there a way to change the address of the automatically generated _binary_*_size symbols? Unlike the _binary_*_start and _binary_*_end symbols, the _binary_*_size symbols don't seem to follow the base address of the code. They are in a bfd absolute section (*ABS*).
For example:
$ arm-linux-gnueabihf-gcc -nostdlib -Wl,-Ttext=0x80000000,--format=binary,foo.bin,--format=default boot.S
$ arm-linux-gnueabihf-nm a.out | sort
00000010 A _binary_foo_bin_size
80000000 T _start
80008004 D _binary_foo_bin_start
80008014 D _binary_foo_bin_end
80008014 A __bss_start
80008014 A __bss_start__
80008014 A __bss_end__
80008014 A _bss_end__
80008014 A _edata
80008014 A _end
80008014 A __end__
I would like _binary_foo_bin_size to be in 0x80008*** instead of 0x00000***.
(Preferably without writing my own linker script or using extra objcopy commands.)

I think the _size symbol records the size of the section. So, offsetting this symbol would be wrong -- it would no longer record the size.
I'm curious why you need to do this. You didn't say. Maybe there is some other way to achieve your goal.

Related

windbg help missing kernel32 function

I am trying to follow this tutorial here https://www.microsoftpressstore.com/articles/article.aspx?p=2201303 specifically the part where it mentions x kernel32!writeprocessmemory
I am unable to find the method kernel32!WriteProcessMemory = even though documentation mentions it but i can find
kernel32!_imp__WriteProcessMemory and kernel32!WriteProcessMemoryStub. I am new to windbg and trying to follow the tutorial so i am not sure if this method has been deprecated and if so, what is it's substitute and how do we achieve similar functionality.
Thanks
The exported WriteProcessMemory function in fact points to the kernel32!WriteProcessMemoryStub stub which itself jumps onto the kernel32!__imp_WriteProcessMemory which redirects to the kernelbase DLL which is the "real" location for this function.
Let's check with a link dump:
C:>link /dump /exports c:\windows\system32\kernel32.dll | findstr /I WriteProcess
1579 62A 00036C50 WriteProcessMemory
0x36C50 is the RVA where the function "WriteProcessMemory" resides in kernel32 (as given by the export table). Now in windbg:
0:007> ln kernel32 + 0x36c50
Browse module
Set bu breakpoint
(00007ff9`4a6e6c50) KERNEL32!WriteProcessMemoryStub | (00007ff9`4a6e6c60) KERNEL32!ZombifyActCtxStub
We have an exact match which is in fact the KERNEL32!WriteProcessMemoryStub function. If we look at it:
0:007> u KERNEL32!WriteProcessMemoryStub
KERNEL32!WriteProcessMemoryStub:
00007ff9`4a6e6c50 48ff2599150400 jmp qword ptr [KERNEL32!_imp_WriteProcessMemory (00007ff9`4a7281f0)]
00007ff9`4a6e6c57 cc int 3
We can see it's just a jump to KERNEL32!_imp_WriteProcessMemory (located somewhere in the .idata section of kernel32).
Now if we look at what is contained at this location, we have a pointer:
0:007> dp KERNEL32!_imp_WriteProcessMemory L1
00007ff9`4a7281f0 00007ff9`496f0ca0
If we ask windbg what is this pointer:
0:007> ln 00007ff9`496f0ca0
Browse module
Set bu breakpoint
(00007ff9`496f0ca0) KERNELBASE!WriteProcessMemory | (00007ff9`496f0dc4) KERNELBASE!OpenWow64CrossProcessWorkConnection
Exact matches:
KERNELBASE!WriteProcessMemory (void)
We can see that in fact the "real" location for the WriteProcessMemory is in fact in kernelbase.dll.
note: you can actually do the last two commands in one with dps:
0:007> dps KERNEL32!_imp_WriteProcessMemory L1
00007ff9`4a7281f0 00007ff9`496f0ca0 KERNELBASE!WriteProcessMemory
Windbg command used:
ln (List Nearest Symbols): given an address, find the nearest symbol.
u (unassemble): used to disassemble a function
dp (display memory): display memory (pointer sized).
dps(Display Words and Symbols): as dp but with symbolic information.

Get parameters of public symbols in WinDBG

I'm debugging an application with WinDBG and the PDB files contain only public symbols, so the "k" command shows only the function names in a call stack. How I can show parameters, too?
I already figured out that I can show decorated names by enabling ".symopt- 2",
so I can use the "undname.exe" that comes with Visual Studio to get the parameters from a decorated name. Essentially, I want that WinDBG does the same thing. Is that possible? Is there a plugin for this?
Many thanks in advance!
(PS: Visual Studio shows the parameters, so it probably does this by default)
the tool dbh.exe in windbg package has an undec command and a -d command line option which you can leverage by loading the exe in a sepearte cmd line window at the same base address as in windbg and examining like below this involves manual copy pasting of the decorated name
an example
dbh -d classmagic.exe
classmagic [1000000]: b 1350000 <-- base as loaded in windbg
classmagic [1350000]: a 1351000
?somecrap##YAHHMND#Z
name : ?somecrap##YAHHMND#Z
addr : 1351000
size : 0
flags : 400000
type : 0
modbase : 1350000
value : 0
reg : 0
scope : SymTagNull (0)
tag : SymTagPublicSymbol (a)
index : 1
classmagic [1350000]: undec ?somecrap##YAHHMND#Z
?somecrap##YAHHMND#Z =
int __cdecl somecrap(int,float,double,char)
classmagic [1350000]:
if you need automation and can accept or improve regex as approriate
1) you should have the gnuwin32 port of unix/linux sed.exe in path (to strip modname from k1 output )
2) instead of undname.exe you should have vc++filt in path
3) you should be able to run the windbg .shell command
4) redecorate the function name with .symopt- symopt_undname
5) run this one liner .shell -ci "k1" sed s/.*!//g | vc++filt
k1 use only one frame (top of stack)
.shell -ci takes a windbg command and passes the commands output to an external application
sed strips the module name and the bang character xxxxx! and pipes it to vc++filt
vc++filt de-mangles the symbol name and returns back the formal
function name to windbg screen
an example below
0:000> k1
ChildEBP RetAddr
001cf904 013513b5 classmagic!?somecrap##YAHHMND#Z
0:000> .shell -ci "k1" sed s/.*!//g | vc++filt
ChildEBP RetAddr
int __cdecl somecrap(int,float,double,char)
It depends on the type of symbols available.
Public symbols, don't contain information about formal parameters. This is explained to great length here (note: this page is also available in the windbg help file, search for "Public and Private Symbols").
Functions, on the other hand, are included both in the private symbol
data and public symbol table, but while the private symbol data
includes the function name, address, FPO records, input parameter
names and types, and output type, the public symbol table includes
just the function name, address, and FPO record.
x, ln (or some other commands like .fnent) should give you this kind of information.
Example with notepad:
0:004> x notepad!RestoreFmt
00007ff7`471251a8 notepad!RestoreFmt (<no parameter info>)
0:004> ln notepad!RestoreFmt
Browse module
Set bu breakpoint
(00007ff7`471251a8) notepad!RestoreFmt | (00007ff7`471251f8) notepad!SaveFile
Exact matches:
notepad!RestoreFmt (<no parameter info>)
Note that <no parameter info> clearly states that the symbols don't contain the required information.
The same applied to another program with private symbolic information:
C++ code:
bool DiskReaderWriter::ReadDisk(off_t offset, size_t size_to_read, std::vector<BYTE>& buffer)
Windbg :
0:001> x drive_rw!DiskReaderWriter::ReadDisk
00000000`00d202c0 drive_rw!DiskReaderWriter::ReadDisk (long, unsigned int, class std::vector<unsigned char,std::allocator<unsigned char> > *)
0:001> ln drive_rw!DiskReaderWriter::ReadDisk
Browse module
Set bu breakpoint
g:\app\cpp\drive_rw\diskreaderwriter.cpp(72)
(00000000`00d202c0) drive_rw!DiskReaderWriter::ReadDisk | (00000000`00d20410) drive_rw!std::_Iterator_base12::_Adopt
Exact matches:
drive_rw!DiskReaderWriter::ReadDisk (long, unsigned int, class std::vector<unsigned char,std::allocator<unsigned char> > *)

Double macro expansion in (AVR-)GCC

please excuse me if this question has already been answered elsewhere, but I'm not sure what to search for.
I am passing a value from a batch file, though a makefile, and to a header file, like so:
(Using AVR-GCC 4.5.2)
Batch:
make ADDR=FOO
Makefile:
CFLAGS += -DADDR=$(ADDR)
...
gcc $(CFLAGS) main.c
This is the header file main.h, included by main.c; it is supposed to select a specific pinout at compile-time, based on the value of ADDR:
#include "defs.h"
#if ADDR == FOO
... // Select pinout 1
#elif ADDR == BAR
... // Select pinout 2
#endif
The comparison values FOO and BAR are constants defined in a global header file defs.h included by main.h:
#define FOO 23
#define BAR 42
Now the problem: The comparisons don't work, ADDR constantly reads as 0. This seems to be because the preprocessor does not resolve ADDR before the comparison, i.e. expand FOO to 23. Telling the compiler to do this expansion would be helpful.
Of course it works if I pass ADDR=23 directly in the batch file, but for flexibility I want to use the aliases from defs.h instead of fixed numeric constants.
By the way, the following works if placed in main.c:
int addr_val = ADDR; // is now 23
Maybe there is a simple solution I am not aware of right now. Please feel free to contribute.
Have a nice day!

Fortran 90 with C/C++ style macro (e.g. # define SUBNAME(x) s ## x)

I am recently working with a F90 code project. I am using gfortran (linux and MinGW) to compile it. There is something interesting in file loct.F90.
# define TYPE real(4)
# define SUBNAME(x) s ## x
# include "loct_inc.F90"
# undef SUBNAME
# undef TYPE
# define TYPE real(8)
# define SUBNAME(x) d ## x
# include "loct_inc.F90"
# undef SUBNAME
# undef TYPE
...
The loct_inc.F90 file looks like this:
subroutine SUBNAME(loct_pointer_copy_1)(o, i)
...
end subroutine SUBNAME(loct_pointer_copy_1)
subroutine SUBNAME(loct_pointer_copy_2)(o, i)
...
end subroutine SUBNAME(loct_pointer_copy_2)
...
I think in the file loct.F90 the author used sets of macros (C/C++ style). Each set is used to define a data type (e.g. real(4), real(8), character, etc). The file loct_inc.F90 provide a set of function which is the same except the type of the variables.
These two files works together as a template of c++ in my opinion.
In the end one should have a set of subroutines:
sloct_pointer_copy_1(o, i)
sloct_pointer_copy_2(o, i)
...
dloct_pointer_copy_1(o, i)
dloct_pointer_copy_2(o, i)
...
But when I tried to compile loct.F90 (gfortran -c loct.F90), I get some errors.
basic/loct_inc.F90:21.13:
Included at basic/loct.F90:256:
subroutine s ## loct_pointer_copy_1(o, i)
1 Error: Syntax error in SUBROUTINE statement at (1)
It seems gfortran replace SUBNAME(loct_pointer_copy_1)(o, i) with s ## loct_pointer_copy_1(o, i). But according to c++ macro, the correct replace should be sloct_pointer_copy_1(o, i).
Could anyone tell me why this happened?
GNU Fortran uses the GNU C Preprocessor in traditional mode, in which mode the macro pasting operator ## is not available. That's why Fortran projects which were written to also compile with the GNU toolchain perform explicit preprocessing in additional Makefile targets, e.g. all *.F90 are first preprocessed with cpp to temporary .f90 files which are then compiled.

lex flex scanner with multiple buffers

I want to use the yy_scan_bytes() as I have null characters defining a rule. My problem is that my string can match more than one rule. I want to get hold of all the rules matched. I want to feed the yylex() function one character at a time and check if something matched. I tried the following code for testing but this doesnt work.
for(int i=0;i<length;i++)
{
yy_scan_bytes(&temp[i],1 );
index=TomsonTalkslex();
}
For simplicity I just return the index of the rule matched from scanner. temp is a char buffer. I tried to use the yy_switch_to_buffer(yy_scan_bytes(&temp[i],1 )); but this didnt work.
How can I tell the scanner not to reset its state and continue processing subsequent buffers with the same state.
Ok, This is just a misunderstanding of how lex/flex works. By default, yylex hooks into stdin, reading until it receives EOF, and matching each rule. That's why it's a tokenizer. So, the sample program below will read from stdin until you enter -c to send an EOF.
%option 8bit outfile="scanner.c"
%option nounput nomain noyywrap
%option warn
%%
ab { fprintf(yyout, "We ran the ab rule.\n"); }
cd { fprintf(yyout, "We ran the cd rule.\n"); }
// echo everything else we find to yyout
. { ECHO; }
\n { ECHO; }
%%
To compile the above, use:
flex -Cf scanner.l
gcc -O -o flexer.exe scanner.c
Save the source file as scanner.l when you do this. Once you compile, you will get a file called flexer.exe in the same directory. Run it from a terminal, and you will get a blank prompt waiting for input. Everything you type will try and match against the rules, until you find only one match. It will then execute the code associated with the rule.
Therefore, if you type abcd, then you will match both the ab and cd rules.
I suggest reading lex and yacc for a more detailed introduction.