Every ELF (Executable Linux Format) file has standard structure.
There is section names that used to identify purpose of section.
Here is example how to write all names of all ELF sections.
Here is steps that we have taken:
1. Find String Table Section
2. Get all section names from string table section
3. Run trough all section an get names of sections
First of all we need get ELF header (Elf32_Ehdr) from position 0.
ELF header have offset of section headers (Elf32_Ehdr.e_shoff).
Sting table section have attributes with help us to recognize it:
1. string table section header address in memory (Elf32_Shdr.sh_addr) is 0
2. its type (Elf32_Shdr.sh_type) is SHT_STRTAB = 3
3. and it is first section with such attributes
To get trough all sections we make for cycle. We can get number
of sections from (Elf32_Ehdr.e_shnum) .
we run all trough all sections and checking for 3 string table section
rules.
for ( iter_s=0; iter_s < ELFheader.e_shnum; iter_s++ )
{
fseek( f, ELFheader.e_shoff+(ELFheader.e_shentsize*iter_s), SEEK_SET);
fread( &STRheader, ELFheader.e_shentsize, 1, f );
if ((STRheader.sh_type == SHT_STRTAB) &&
(STRheader.sh_addr == 0x00000000))
{
//some code
iter_s=ELFheader.e_shnum+1; //this is to exit from for cycle
}
}
String table section has all section names as strings. Section name
is in (Elf32_Shdr.sh_name) as position number of strings first symbol.
All string table values we read inside buffer
fseek( f, STRheader.sh_offset, SEEK_SET);
fread( STR_buffer, STRheader.sh_size, 1, f);
Now we can get section name with
printf("%s\n", STR_buffer+ITERheader.sh_name);
This is example code to get some info from ELF file. There is allot other
info that can be gained from ELF file.
There is long time since wanted to learn "creepy" gcc inline assembly.
Looking at manuals its not so hard and "creepy". Using it is more
interesting and dissambly of compiled code is very nice looking.
volatile puts our asm code where it is and don't optimize it without
volatile it can optimize.
What to write in __asm__ directive looks like this
__asm__ __volatile__("our_code":output:input:used)
as code to convert to inline asm we will use last post [2].
There is only one instruction that we using and it usage was
get_timer:
rdtsc
ret
its not very optimal and for 1 instruction writing whole function
its not beautiful. We remember that returning result of this function is
saved in eax register.
__asm__ __volatile__("rdtsc":"=a"(x)::)
code looks like this. But we can make it as define function
#define get_timer(X) __asm__ __volatile__("rdtsc":"=a"(X)::)
This code works fine and give 70058 ticks on cycle
When adding option -O2 then result becomes wherry strange.
As we remember that rdtsc return result in edx:eax then we add to
used registers(clobber) %edx.
#define get_timer(X) __asm__ __volatile__("rdtsc":"=a"(X)::"%edx")
And also we can rewrite everything as
inline function.
static inline unsigned int get_timeri()
{
unsigned int i;
__asm__ __volatile__("rdtsc":"=a"(i)::);
return i;
}
Now this two functions works fine with -O options.
When empty cycle is optimized then it becomes empty and resulting
tick number is 32 for both inline function and define macro.
It not working for his main purpose. When no optimization switched
then get_timer works for some ticks faster then get_timeri.
We can add attribute always inline and we will win some ticks
and function will always inline regards optimization level
__attribute__((always_inline)) unsigned int get_timeri()
Too fix test cycle for our measurement we make it as object file
and it will compiled without options.
void fixed_cycle()
{
int i;
for (i=0;i<10000;i++)
{
}
}
Now everything looks quite good and also inline assembly works as expected.
For reference about inline asm you can go to [1]
Source
Links
[1]http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html
[2]http://main.lv/post/linux-antidebug-5
When debuging programm line by line or when running it
in some debugger then ther can be some time delays when you
pressing buttons. We can measure them with asm command
rdtsc
this instruction read time-stamp counter into edx:eax in our programm will be enought values from
eax
function for c that uses rdtsc is
extern int get_timer()
in fasm it looks like
get_timer:
rdtsc
ret
ther is writen code
s = get_timer();
for (i=0;i<10000;i++)
{
}
e = get_timer();
d = e - s;
average time to execute 10000 is 70069 ticks for value
on with we detecting how fast working code i have choose
twice of average 120000 if execution time is larger then
probably it is debuged.
Compile
make