ELF-Editing: Replacing function in it's own section with different function - linker

I have a .o object file which has a function that other functions in that same file are calling. That function is in it's own section and not exported. I need to replace this function with my own implementation. My own implementation needs external symbols aswell. I thought about simply patching that section so it calls an address that's placed at some location (so the old function is effectively just transfering control to my code), then I only need to add some kind of reference/relocation information so the linker knows that it needs to place the address of the function at that location (it looks like that's how it's done for all the other "imports"). But how do I do this using tools like objcopy, ld, gcc, and nm? Unfortunately I can't really use any additional tools (except for those present on a normal linux machine like sed, awk, dd and so on). I can see that the other imported symbols are listed in the symtab without an address and so on, but I can't see how they are referred to.
The output of readelf -Ws is
Symbol table '.symtab' contains 190 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 SECTION LOCAL DEFAULT 57
2: 00000000 0 SECTION LOCAL DEFAULT 58
3: 00000000 0 SECTION LOCAL DEFAULT 59
4: 00000000 0 SECTION LOCAL DEFAULT 61
5: 00000000 0 SECTION LOCAL DEFAULT 62
6: 00000000 0 SECTION LOCAL DEFAULT 64
7: 00000000 0 SECTION LOCAL DEFAULT 66
8: 00000000 0 SECTION LOCAL DEFAULT 68
9: 00000000 0 SECTION LOCAL DEFAULT 70
10: 00000000 0 SECTION LOCAL DEFAULT 72
11: 00000000 0 SECTION LOCAL DEFAULT 74
12: 00000000 0 SECTION LOCAL DEFAULT 76
13: 00000000 0 SECTION LOCAL DEFAULT 78
14: 00000000 0 SECTION LOCAL DEFAULT 80
15: 00000000 0 SECTION LOCAL DEFAULT 82
16: 00000000 0 SECTION LOCAL DEFAULT 84
17: 00000000 0 SECTION LOCAL DEFAULT 86
18: 00000000 0 SECTION LOCAL DEFAULT 88
19: 00000000 0 SECTION LOCAL DEFAULT 90
20: 00000000 0 SECTION LOCAL DEFAULT 92
21: 00000000 0 SECTION LOCAL DEFAULT 94
22: 00000000 0 SECTION LOCAL DEFAULT 96
23: 00000000 0 SECTION LOCAL DEFAULT 98
24: 00000000 0 SECTION LOCAL DEFAULT 100
25: 00000000 0 SECTION LOCAL DEFAULT 102
26: 00000000 0 SECTION LOCAL DEFAULT 104
27: 00000000 0 SECTION LOCAL DEFAULT 105
28: 00000000 0 SECTION LOCAL DEFAULT 107
29: 00000000 0 SECTION LOCAL DEFAULT 109
30: 00000000 0 SECTION LOCAL DEFAULT 111
31: 00000000 0 SECTION LOCAL DEFAULT 113
32: 00000000 0 SECTION LOCAL DEFAULT 115
33: 00000000 0 SECTION LOCAL DEFAULT 117
34: 00000000 0 SECTION LOCAL DEFAULT 119
35: 00000000 0 SECTION LOCAL DEFAULT 121
36: 00000000 0 SECTION LOCAL DEFAULT 123
37: 00000000 0 SECTION LOCAL DEFAULT 125
38: 00000000 0 SECTION LOCAL DEFAULT 126
39: 00000000 0 SECTION LOCAL DEFAULT 128
40: 00000000 0 SECTION LOCAL DEFAULT 130
41: 00000000 0 SECTION LOCAL DEFAULT 132
42: 00000000 0 SECTION LOCAL DEFAULT 134
43: 00000000 0 SECTION LOCAL DEFAULT 136
44: 00000000 0 SECTION LOCAL DEFAULT 138
45: 00000000 0 SECTION LOCAL DEFAULT 140
46: 00000000 0 SECTION LOCAL DEFAULT 142
47: 00000000 0 SECTION LOCAL DEFAULT 144
48: 00000000 0 SECTION LOCAL DEFAULT 146
49: 00000000 0 SECTION LOCAL DEFAULT 148
50: 00000000 0 SECTION LOCAL DEFAULT 150
51: 00000000 0 SECTION LOCAL DEFAULT 152
52: 00000000 0 SECTION LOCAL DEFAULT 154
53: 00000000 0 SECTION LOCAL DEFAULT 156
54: 00000000 0 SECTION LOCAL DEFAULT 158
55: 00000000 0 SECTION LOCAL DEFAULT 160
56: 00000000 0 SECTION LOCAL DEFAULT 162
57: 00000000 0 SECTION LOCAL DEFAULT 164
58: 00000000 0 SECTION LOCAL DEFAULT 166
59: 00000000 0 SECTION LOCAL DEFAULT 168
60: 00000000 0 SECTION LOCAL DEFAULT 1
61: 00000000 0 SECTION LOCAL DEFAULT 2
62: 00000000 0 SECTION LOCAL DEFAULT 3
63: 00000000 0 SECTION LOCAL DEFAULT 4
64: 00000000 0 SECTION LOCAL DEFAULT 5
65: 00000000 0 SECTION LOCAL DEFAULT 6
66: 00000000 0 SECTION LOCAL DEFAULT 7
67: 00000000 0 SECTION LOCAL DEFAULT 8
68: 00000000 0 SECTION LOCAL DEFAULT 9
69: 00000000 0 SECTION LOCAL DEFAULT 10
70: 00000000 0 SECTION LOCAL DEFAULT 11
71: 00000000 0 SECTION LOCAL DEFAULT 12
72: 00000000 0 SECTION LOCAL DEFAULT 13
73: 00000000 0 SECTION LOCAL DEFAULT 14
74: 00000000 0 SECTION LOCAL DEFAULT 15
75: 00000000 0 SECTION LOCAL DEFAULT 16
76: 00000000 0 SECTION LOCAL DEFAULT 17
77: 00000000 0 SECTION LOCAL DEFAULT 18
78: 00000000 0 SECTION LOCAL DEFAULT 19
79: 00000000 0 SECTION LOCAL DEFAULT 20
80: 00000000 0 SECTION LOCAL DEFAULT 21
81: 00000000 0 SECTION LOCAL DEFAULT 22
82: 00000000 0 SECTION LOCAL DEFAULT 23
83: 00000000 0 SECTION LOCAL DEFAULT 24
84: 00000000 0 SECTION LOCAL DEFAULT 25
85: 00000000 0 SECTION LOCAL DEFAULT 26
86: 00000000 0 SECTION LOCAL DEFAULT 27
87: 00000000 0 SECTION LOCAL DEFAULT 28
88: 00000000 0 SECTION LOCAL DEFAULT 29
89: 00000000 0 SECTION LOCAL DEFAULT 30
90: 00000000 0 SECTION LOCAL DEFAULT 31
91: 00000000 0 SECTION LOCAL DEFAULT 32
92: 00000000 0 SECTION LOCAL DEFAULT 33
93: 00000000 0 SECTION LOCAL DEFAULT 34
94: 00000000 0 SECTION LOCAL DEFAULT 35
95: 00000000 0 SECTION LOCAL DEFAULT 36
96: 00000000 0 SECTION LOCAL DEFAULT 37
97: 00000000 0 SECTION LOCAL DEFAULT 38
98: 00000000 0 SECTION LOCAL DEFAULT 39
99: 00000000 0 SECTION LOCAL DEFAULT 40
100: 00000000 0 SECTION LOCAL DEFAULT 41
101: 00000000 0 SECTION LOCAL DEFAULT 42
102: 00000000 0 SECTION LOCAL DEFAULT 43
103: 00000000 0 SECTION LOCAL DEFAULT 44
104: 00000000 0 SECTION LOCAL DEFAULT 45
105: 00000000 0 SECTION LOCAL DEFAULT 46
106: 00000000 0 SECTION LOCAL DEFAULT 47
107: 00000000 0 SECTION LOCAL DEFAULT 48
108: 00000000 0 SECTION LOCAL DEFAULT 49
109: 00000000 0 SECTION LOCAL DEFAULT 50
110: 00000000 0 SECTION LOCAL DEFAULT 51
111: 00000000 0 SECTION LOCAL DEFAULT 52
112: 00000000 0 SECTION LOCAL DEFAULT 53
113: 00000000 0 SECTION LOCAL DEFAULT 54
114: 00000000 0 SECTION LOCAL DEFAULT 55
115: 00000000 0 SECTION LOCAL DEFAULT 56
116: 00000000 0 SECTION LOCAL DEFAULT 170
117: 00000000 0 SECTION LOCAL DEFAULT 171
118: 00000000 0 SECTION LOCAL DEFAULT 172
119: 00000000 0 SECTION LOCAL DEFAULT 174
120: 00000000 0 NOTYPE GLOBAL DEFAULT UND wpabuf_put
121: 00000004 30 FUNC GLOBAL DEFAULT 64 eap_peer_get_eap_method
122: 00000004 29 FUNC GLOBAL DEFAULT 66 eap_peer_get_methods
123: 00000008 65 FUNC GLOBAL DEFAULT 68 eap_peer_get_type
124: 00000000 0 NOTYPE GLOBAL DEFAULT UND ets_strcmp
125: 00000008 52 FUNC GLOBAL DEFAULT 72 eap_get_phase2_type
126: 00000010 136 FUNC GLOBAL DEFAULT 74 eap_get_phase2_types
127: 00000000 0 NOTYPE GLOBAL DEFAULT UND pvPortMalloc
128: 00000008 51 FUNC GLOBAL DEFAULT 76 eap_peer_method_alloc
129: 00000000 0 NOTYPE GLOBAL DEFAULT UND pvPortZalloc
130: 00000008 24 FUNC GLOBAL DEFAULT 78 eap_peer_method_free
131: 00000000 0 NOTYPE GLOBAL DEFAULT UND vPortFree
132: 0000000c 99 FUNC GLOBAL DEFAULT 80 eap_peer_method_register
133: 00000008 48 FUNC GLOBAL DEFAULT 82 eap_peer_unregister_methods
134: 00000010 42 FUNC GLOBAL DEFAULT 84 eap_peer_register_methods
135: 00000000 0 NOTYPE GLOBAL DEFAULT UND eap_peer_tls_register
136: 00000000 0 NOTYPE GLOBAL DEFAULT UND eap_peer_mschapv2_register
137: 00000000 0 NOTYPE GLOBAL DEFAULT UND eap_peer_peap_register
138: 00000000 0 NOTYPE GLOBAL DEFAULT UND eap_peer_ttls_register
139: 00000000 0 NOTYPE GLOBAL DEFAULT UND g_ic
140: 00000000 0 NOTYPE GLOBAL DEFAULT UND ieee80211_output_pbuf
141: 00000000 0 NOTYPE GLOBAL DEFAULT UND ets_memset
142: 00000000 0 NOTYPE GLOBAL DEFAULT UND ets_memcpy
143: 00000008 59 FUNC GLOBAL DEFAULT 92 wpa2_sm_alloc_eapol
144: 00000000 0 NOTYPE GLOBAL DEFAULT UND pbuf_alloc
145: 00000020 145 FUNC GLOBAL DEFAULT 96 eap_sm_build_identity_resp
146: 00000000 5 FUNC GLOBAL DEFAULT 125 eap_get_config
147: 00000000 0 NOTYPE GLOBAL DEFAULT UND os_printf_plus
148: 00000000 0 NOTYPE GLOBAL DEFAULT UND eap_msg_alloc
149: 00000000 0 NOTYPE GLOBAL DEFAULT UND eap_update_len
150: 00000010 79 FUNC GLOBAL DEFAULT 100 eap_sm_send_eapol
151: 00000034 454 FUNC GLOBAL DEFAULT 102 eap_sm_process_request
152: 00000000 0 NOTYPE GLOBAL DEFAULT UND wpabuf_free
153: 0000001c 188 FUNC GLOBAL DEFAULT 105 wpa2_sm_rx_eapol
154: 00000000 0 NOTYPE GLOBAL DEFAULT UND wpabuf_alloc_copy
155: 00000000 0 NOTYPE GLOBAL DEFAULT UND wpa_set_pmk
156: 00000000 0 NOTYPE GLOBAL DEFAULT UND ets_bzero
157: 00000000 0 NOTYPE GLOBAL DEFAULT UND ets_strncpy
158: 00000000 0 NOTYPE GLOBAL DEFAULT UND wifi_get_macaddr
159: 00000000 0 NOTYPE GLOBAL DEFAULT UND tls_init
160: 00000000 0 NOTYPE GLOBAL DEFAULT UND tls_deinit
161: 00000004 37 FUNC GLOBAL DEFAULT 126 eap_get_config_identity
162: 00000004 37 FUNC GLOBAL DEFAULT 128 eap_get_config_password
163: 00000004 51 FUNC GLOBAL DEFAULT 130 eap_get_config_password2
164: 00000004 39 FUNC GLOBAL DEFAULT 132 eap_get_config_new_password
165: 00000004 63 FUNC GLOBAL DEFAULT 134 eap_get_config_blob
166: 00000000 0 NOTYPE GLOBAL DEFAULT UND ets_strncmp
167: 00000048 164 FUNC GLOBAL DEFAULT 136 wifi_station_set_wpa2_enterprise_auth
168: 00000004 36 FUNC GLOBAL DEFAULT 138 wifi_station_set_enterprise_cert_key
169: 00000004 21 FUNC GLOBAL DEFAULT 140 wifi_station_clear_enterprise_cert_key
170: 00000004 16 FUNC GLOBAL DEFAULT 142 wifi_station_set_enterprise_ca_cert
171: 00000004 11 FUNC GLOBAL DEFAULT 144 wifi_station_clear_enterprise_ca_cert
172: 00000024 109 FUNC GLOBAL DEFAULT 146 wifi_station_set_enterprise_identity
173: 00000010 40 FUNC GLOBAL DEFAULT 148 wifi_station_clear_enterprise_identity
174: 00000024 109 FUNC GLOBAL DEFAULT 150 wifi_station_set_enterprise_username
175: 00000010 40 FUNC GLOBAL DEFAULT 152 wifi_station_clear_enterprise_username
176: 00000024 103 FUNC GLOBAL DEFAULT 154 wifi_station_set_enterprise_password
177: 00000010 40 FUNC GLOBAL DEFAULT 156 wifi_station_clear_enterprise_password
178: 00000024 103 FUNC GLOBAL DEFAULT 158 wifi_station_set_enterprise_new_password
179: 00000010 40 FUNC GLOBAL DEFAULT 160 wifi_station_clear_enterprise_new_password
180: 00000004 8 FUNC GLOBAL DEFAULT 162 wifi_station_set_enterprise_disable_time_check
181: 00000004 8 FUNC GLOBAL DEFAULT 164 wifi_station_get_enterprise_disable_time_check
182: 00000004 8 FUNC GLOBAL DEFAULT 166 wpa2_enterprise_set_user_get_time
183: 00000004 28 FUNC GLOBAL DEFAULT 168 wpa2_get_time
184: 00000004 36 FUNC GLOBAL DEFAULT 138 wifi_station_set_cert_key
185: 00000004 21 FUNC GLOBAL DEFAULT 140 wifi_station_clear_cert_key
186: 00000024 109 FUNC GLOBAL DEFAULT 146 wifi_station_set_identity
187: 00000010 40 FUNC GLOBAL DEFAULT 148 wifi_station_clear_identity
188: 00000024 109 FUNC GLOBAL DEFAULT 150 wifi_station_set_username
189: 00000010 40 FUNC GLOBAL DEFAULT 152 wifi_station_clear_username
and readelf -t says this about the section/function I need to modify:
There are 179 section headers, starting at offset 0x96b0:
Section Headers:
[Nr] Name
Type Addr Off Size ES Lk Inf Al
Flags
...
[113] .text.eap_peer_config_deinit
PROGBITS 00000000 000dd0 000868 00 0 0 4
[00000006]: ALLOC, EXEC
[114] .rela.text.eap_peer_config_deinit
RELA 00000000 005d68 000000 0c 176 113 4
[00000040]: INFO LINK
I had to cut the output as I reached the character limit.

I have a .o object file which has a function that other functions in that same file are calling. That function is in it's own section and not exported.
The function I want to modify is basically calling free on the first member of a struct and then zeroing out that struct. I need to call free on the other members of the struct as well before it's all zeroed out.
The simplest solution is to remove the function from the .o file with objcopy --remove-section ... --remove-relocations ..., and add your own implementation in a separate .o.
That's much simpler than editing existing .o to "splice in" different implementation, and appears to satisfy your requirements.

Related

Why does gcc produce different compiled binaries for programs that use different forms of integer literals?

I was wondering what the difference between:
int a = 0b00000100;
int a = 0x04;
int a = 4;
When compiled with gcc.
I seem to get a different binary when compiling with what seems to be the same number, just in different notations. When I run objdump on it however, there doesn't seem to be any differences. Could somebody tell me what's going on?
This is my output:
marshall#dont.even.try.to.h4ck.me:[~]: cat testbin.c && echo && cat testbin2.c
#include "stdio.h"
int main () {
int a = 0b00000100;
int b = 0x05;
int c = 6;
printf("%d - %d - %d\n", a, b, c);
return (0);
}
#include "stdio.h"
int main () {
int a = 4;
int b = 5;
int c = 6;
printf("%d - %d - %d\n", a, b, c);
return (0);
}
marshall#dont.even.try.to.h4ck.me:[~]: gcc testbin.c -o testbin
marshall#dont.even.try.to.h4ck.me:[~]: gcc testbin2.c -o testbin2
marshall#dont.even.try.to.h4ck.me:[~]: md5sum testbin testbin2
fd6aaa31bdf685ea9444e1edc209565e testbin
3a3fc241bfc2917ee29999b5befecd2a testbin2
marshall#dont.even.try.to.h4ck.me:[~]: objdump -d testbin > testbin.obj && objdump -d testbin2 > testbin2.obj
marshall#dont.even.try.to.h4ck.me:[~]: diff testbin.obj testbin2.obj
2c2
< testbin: file format elf64-x86-64
---
> testbin2: file format elf64-x86-64
marshall#dont.even.try.to.h4ck.me:[~]: gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/6/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 6.3.0-18' --with-bugurl=file:///usr/share/doc/gcc-6/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-6 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-6-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-6-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-6-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 6.3.0 20170516 (Debian 6.3.0-18)
marshall#dont.even.try.to.h4ck.me:[~]:
Notice that the executables are different, they have different hashes, but objdump -d doesn't show anything different.
I think that the issue has nothing to do with the integer formats and everything to do with the filenames.
I compiled the following program twice, first using the filename FIRST_PROG.c and executable name COMPILED_1 and the second time using the filename SECOND_PROC.c and executable name COMPILED_2 using gcc with no other flags set:
int main() {
return 0;
}
If you hd the contents of the generated executable, at a certain offset you see this:
00001720 66 72 61 6d 65 5f 64 75 6d 6d 79 5f 69 6e 69 74 |frame_dummy_init|
00001730 5f 61 72 72 61 79 5f 65 6e 74 72 79 00 46 49 52 |_array_entry.FIR|
00001740 53 54 5f 50 52 4f 47 2e 63 00 5f 5f 46 52 41 4d |ST_PROG.c.__FRAM|
Notice that the name of the source file, FIRST_PROG.c, is embedded into the generated executable. Looking at the same location in the second file shows this:
00001720 66 72 61 6d 65 5f 64 75 6d 6d 79 5f 69 6e 69 74 |frame_dummy_init|
00001730 5f 61 72 72 61 79 5f 65 6e 74 72 79 00 53 45 43 |_array_entry.SEC|
00001740 4f 4e 44 5f 50 52 4f 47 2e 63 00 5f 5f 46 52 41 |OND_PROG.c.__FRA|
You can see SECOND_PROG.c is embedded into the binary as well.
Dumping both executables with objdump -s doesn't show this anywhere, which matches the clean diff you had from your programs. However, using readelf -a to list the contents of the executable that's generated does show this:
Symbol table '.symtab' contains 66 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000400238 0 SECTION LOCAL DEFAULT 1
2: 0000000000400254 0 SECTION LOCAL DEFAULT 2
3: 0000000000400274 0 SECTION LOCAL DEFAULT 3
4: 0000000000400298 0 SECTION LOCAL DEFAULT 4
5: 00000000004002b8 0 SECTION LOCAL DEFAULT 5
6: 0000000000400300 0 SECTION LOCAL DEFAULT 6
7: 0000000000400338 0 SECTION LOCAL DEFAULT 7
8: 0000000000400340 0 SECTION LOCAL DEFAULT 8
9: 0000000000400360 0 SECTION LOCAL DEFAULT 9
10: 0000000000400378 0 SECTION LOCAL DEFAULT 10
11: 0000000000400390 0 SECTION LOCAL DEFAULT 11
12: 00000000004003b0 0 SECTION LOCAL DEFAULT 12
13: 00000000004003d0 0 SECTION LOCAL DEFAULT 13
14: 00000000004003e0 0 SECTION LOCAL DEFAULT 14
15: 0000000000400564 0 SECTION LOCAL DEFAULT 15
16: 0000000000400570 0 SECTION LOCAL DEFAULT 16
17: 0000000000400574 0 SECTION LOCAL DEFAULT 17
18: 00000000004005a8 0 SECTION LOCAL DEFAULT 18
19: 0000000000600e10 0 SECTION LOCAL DEFAULT 19
20: 0000000000600e18 0 SECTION LOCAL DEFAULT 20
21: 0000000000600e20 0 SECTION LOCAL DEFAULT 21
22: 0000000000600e28 0 SECTION LOCAL DEFAULT 22
23: 0000000000600ff8 0 SECTION LOCAL DEFAULT 23
24: 0000000000601000 0 SECTION LOCAL DEFAULT 24
25: 0000000000601020 0 SECTION LOCAL DEFAULT 25
26: 0000000000601030 0 SECTION LOCAL DEFAULT 26
27: 0000000000000000 0 SECTION LOCAL DEFAULT 27
28: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
29: 0000000000600e20 0 OBJECT LOCAL DEFAULT 21 __JCR_LIST__
30: 0000000000400410 0 FUNC LOCAL DEFAULT 14 deregister_tm_clones
31: 0000000000400450 0 FUNC LOCAL DEFAULT 14 register_tm_clones
32: 0000000000400490 0 FUNC LOCAL DEFAULT 14 __do_global_dtors_aux
33: 0000000000601030 1 OBJECT LOCAL DEFAULT 26 completed.7585
34: 0000000000600e18 0 OBJECT LOCAL DEFAULT 20 __do_global_dtors_aux_fin
35: 00000000004004b0 0 FUNC LOCAL DEFAULT 14 frame_dummy
36: 0000000000600e10 0 OBJECT LOCAL DEFAULT 19 __frame_dummy_init_array_
37: 0000000000000000 0 FILE LOCAL DEFAULT ABS FIRST_PROG.c
38: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
39: 0000000000400698 0 OBJECT LOCAL DEFAULT 18 __FRAME_END__
40: 0000000000600e20 0 OBJECT LOCAL DEFAULT 21 __JCR_END__
41: 0000000000000000 0 FILE LOCAL DEFAULT ABS
42: 0000000000600e18 0 NOTYPE LOCAL DEFAULT 19 __init_array_end
43: 0000000000600e28 0 OBJECT LOCAL DEFAULT 22 _DYNAMIC
44: 0000000000600e10 0 NOTYPE LOCAL DEFAULT 19 __init_array_start
45: 0000000000400574 0 NOTYPE LOCAL DEFAULT 17 __GNU_EH_FRAME_HDR
46: 0000000000601000 0 OBJECT LOCAL DEFAULT 24 _GLOBAL_OFFSET_TABLE_
47: 0000000000400560 2 FUNC GLOBAL DEFAULT 14 __libc_csu_fini
48: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTab
49: 0000000000601020 0 NOTYPE WEAK DEFAULT 25 data_start
50: 0000000000601030 0 NOTYPE GLOBAL DEFAULT 25 _edata
51: 0000000000400564 0 FUNC GLOBAL DEFAULT 15 _fini
52: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main##GLIBC_
53: 0000000000601020 0 NOTYPE GLOBAL DEFAULT 25 __data_start
54: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
55: 0000000000601028 0 OBJECT GLOBAL HIDDEN 25 __dso_handle
56: 0000000000400570 4 OBJECT GLOBAL DEFAULT 16 _IO_stdin_used
57: 00000000004004f0 101 FUNC GLOBAL DEFAULT 14 __libc_csu_init
58: 0000000000601038 0 NOTYPE GLOBAL DEFAULT 26 _end
59: 00000000004003e0 42 FUNC GLOBAL DEFAULT 14 _start
60: 0000000000601030 0 NOTYPE GLOBAL DEFAULT 26 __bss_start
61: 00000000004004d6 11 FUNC GLOBAL DEFAULT 14 main
62: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses
63: 0000000000601030 0 OBJECT GLOBAL HIDDEN 25 __TMC_END__
64: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable
65: 0000000000400390 0 FUNC GLOBAL DEFAULT 11 _init
Notice that entry 37 contains the name of the source file. If you try diffing the output of readelf -a, you do get some pretty helpful information:
81c81
< [28] .shstrtab STRTAB 0000000000000000 0000189f
---
> [28] .shstrtab STRTAB 0000000000000000 000018a0
86c86
< 0000000000000207 0000000000000000 0 0 1
---
> 0000000000000208 0000000000000000 0 0 1
211c211
< 37: 0000000000000000 0 FILE LOCAL DEFAULT ABS FIRST_PROG.c
---
> 37: 0000000000000000 0 FILE LOCAL DEFAULT ABS SECOND_PROG.c
258c258
< Build ID: 2c64961288049002e34a1f14e55d6c80dd96816c
---
> Build ID: 5425dec81aae53bd30e85fe94659d320bb774dcc
It seems like many of these differences boil down to just having a different name for the source file.
So my official answer is "this has nothing whatsoever to do with integer literals and is purely a function of compiling files with different names."

ELF Binary: why symbol value is different from actual symbol address? [duplicate]

readelf output of the object file:
Symbol table '.symtab' contains 15 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 FILE LOCAL DEFAULT ABS fp16.c
2: 00000000 0 SECTION LOCAL DEFAULT 1
3: 00000000 0 SECTION LOCAL DEFAULT 3
4: 00000000 0 SECTION LOCAL DEFAULT 4
5: 00000000 0 NOTYPE LOCAL DEFAULT 1 $t
6: 00000001 194 FUNC LOCAL DEFAULT 1 __gnu_f2h_internal
7: 00000010 0 NOTYPE LOCAL DEFAULT 5 $d
8: 00000000 0 SECTION LOCAL DEFAULT 5
9: 00000000 0 SECTION LOCAL DEFAULT 7
10: 000000c5 78 FUNC GLOBAL HIDDEN 1 __gnu_h2f_internal
11: 00000115 4 FUNC GLOBAL HIDDEN 1 __gnu_f2h_ieee
12: 00000119 4 FUNC GLOBAL HIDDEN 1 __gnu_h2f_ieee
13: 0000011d 4 FUNC GLOBAL HIDDEN 1 __gnu_f2h_alternative
14: 00000121 4 FUNC GLOBAL HIDDEN 1 __gnu_h2f_alternative
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 00000000 000034 000124 00 AX 0 0 4
[ 2] .rel.text REL 00000000 00058c 000010 08 9 1 4
[ 3] .data PROGBITS 00000000 000158 000000 00 WA 0 0 1
[ 4] .bss NOBITS 00000000 000158 000000 00 WA 0 0 1
[ 5] .debug_frame PROGBITS 00000000 000158 00008c 00 0 0 4
[ 6] .rel.debug_frame REL 00000000 00059c 000060 08 9 5 4
[ 7] .ARM.attributes ARM_ATTRIBUTES 00000000 0001e4 00002f 00 0 0 1
[ 8] .shstrtab STRTAB 00000000 000213 000051 00 0 0 1
[ 9] .symtab SYMTAB 00000000 00041c 0000f0 10 10 10 4
[10] .strtab STRTAB 00000000 00050c 00007e 00 0 0 1
Relocation section '.rel.text' at offset 0x58c contains 2 entries:
Offset Info Type Sym.Value Sym. Name
0000011a 00000a66 R_ARM_THM_JUMP11 000000c5 __gnu_h2f_internal
00000122 00000a66 R_ARM_THM_JUMP11 000000c5 __gnu_h2f_internal
Relocation section '.rel.debug_frame' at offset 0x59c contains 12 entries:
Offset Info Type Sym.Value Sym. Name
00000014 00000802 R_ARM_ABS32 00000000 .debug_frame
00000018 00000202 R_ARM_ABS32 00000000 .text
00000040 00000802 R_ARM_ABS32 00000000 .debug_frame
00000044 00000202 R_ARM_ABS32 00000000 .text
00000050 00000802 R_ARM_ABS32 00000000 .debug_frame
00000054 00000202 R_ARM_ABS32 00000000 .text
00000060 00000802 R_ARM_ABS32 00000000 .debug_frame
00000064 00000202 R_ARM_ABS32 00000000 .text
00000070 00000802 R_ARM_ABS32 00000000 .debug_frame
00000074 00000202 R_ARM_ABS32 00000000 .text
00000080 00000802 R_ARM_ABS32 00000000 .debug_frame
00000084 00000202 R_ARM_ABS32 00000000 .text
.text section structure as I understand it:
.text section has size of 0x124
0x0: unknown byte
0x1-0xC3: __gnu_f2h_internal
0xC3-0xC5: two unknown bytes between those functions (btw what are those?)
0xC5-0x113: __gnu_h2f_internal
0x113-0x115: two unknown bytes between those functions
0x115-0x119: __gnu_f2h_ieee
0x119-0x11D: __gnu_h2f_ieee
0x11D-0x121: __gnu_f2h_alternative
0x121-0x125: __gnu_h2f_alternative // section is only 0x124, what happened to the missing byte?
Notice that the section size is 0x124 and the last function end in 0x125, what happend to the missing byte?
Thanks.
Technically, your "missing byte" is the one right there at 0x0.
Note that you're looking at the value of the symbol, i.e. the runtime function address (this would be a lot clearer if your .text section VMA wasn't 0). Since they're Thumb functions, the addresses have bit 0 set such that the processor will switch to Thumb mode when calling them; the actual locations of those instructions are still halfword-aligned, i.e. 0x0, 0xc4, 0x114, etc. since they couldn't be executed otherwise (you'd take a fault for a misaligned PC). Strip off bit 0 as per what the ARM
ELF spec says about STT_FUNC symbols to get the actual VMA of the instruction corresponding to that symbol, then subtract the start of the section and you should have the same relative offset as within the object file itself.
<offset in section> = (<symbol value> & ~1) - <section VMA>
The extra halfword padding after some functions just ensures each symbol is word-aligned - there are probably various reasons for this, but the first one that comes to mind is that the adr instruction wouldn't work properly if they weren't.

Incorrect function size inside ARM ELF object

readelf output of the object file:
Symbol table '.symtab' contains 15 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00000000 0 FILE LOCAL DEFAULT ABS fp16.c
2: 00000000 0 SECTION LOCAL DEFAULT 1
3: 00000000 0 SECTION LOCAL DEFAULT 3
4: 00000000 0 SECTION LOCAL DEFAULT 4
5: 00000000 0 NOTYPE LOCAL DEFAULT 1 $t
6: 00000001 194 FUNC LOCAL DEFAULT 1 __gnu_f2h_internal
7: 00000010 0 NOTYPE LOCAL DEFAULT 5 $d
8: 00000000 0 SECTION LOCAL DEFAULT 5
9: 00000000 0 SECTION LOCAL DEFAULT 7
10: 000000c5 78 FUNC GLOBAL HIDDEN 1 __gnu_h2f_internal
11: 00000115 4 FUNC GLOBAL HIDDEN 1 __gnu_f2h_ieee
12: 00000119 4 FUNC GLOBAL HIDDEN 1 __gnu_h2f_ieee
13: 0000011d 4 FUNC GLOBAL HIDDEN 1 __gnu_f2h_alternative
14: 00000121 4 FUNC GLOBAL HIDDEN 1 __gnu_h2f_alternative
Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
[ 1] .text PROGBITS 00000000 000034 000124 00 AX 0 0 4
[ 2] .rel.text REL 00000000 00058c 000010 08 9 1 4
[ 3] .data PROGBITS 00000000 000158 000000 00 WA 0 0 1
[ 4] .bss NOBITS 00000000 000158 000000 00 WA 0 0 1
[ 5] .debug_frame PROGBITS 00000000 000158 00008c 00 0 0 4
[ 6] .rel.debug_frame REL 00000000 00059c 000060 08 9 5 4
[ 7] .ARM.attributes ARM_ATTRIBUTES 00000000 0001e4 00002f 00 0 0 1
[ 8] .shstrtab STRTAB 00000000 000213 000051 00 0 0 1
[ 9] .symtab SYMTAB 00000000 00041c 0000f0 10 10 10 4
[10] .strtab STRTAB 00000000 00050c 00007e 00 0 0 1
Relocation section '.rel.text' at offset 0x58c contains 2 entries:
Offset Info Type Sym.Value Sym. Name
0000011a 00000a66 R_ARM_THM_JUMP11 000000c5 __gnu_h2f_internal
00000122 00000a66 R_ARM_THM_JUMP11 000000c5 __gnu_h2f_internal
Relocation section '.rel.debug_frame' at offset 0x59c contains 12 entries:
Offset Info Type Sym.Value Sym. Name
00000014 00000802 R_ARM_ABS32 00000000 .debug_frame
00000018 00000202 R_ARM_ABS32 00000000 .text
00000040 00000802 R_ARM_ABS32 00000000 .debug_frame
00000044 00000202 R_ARM_ABS32 00000000 .text
00000050 00000802 R_ARM_ABS32 00000000 .debug_frame
00000054 00000202 R_ARM_ABS32 00000000 .text
00000060 00000802 R_ARM_ABS32 00000000 .debug_frame
00000064 00000202 R_ARM_ABS32 00000000 .text
00000070 00000802 R_ARM_ABS32 00000000 .debug_frame
00000074 00000202 R_ARM_ABS32 00000000 .text
00000080 00000802 R_ARM_ABS32 00000000 .debug_frame
00000084 00000202 R_ARM_ABS32 00000000 .text
.text section structure as I understand it:
.text section has size of 0x124
0x0: unknown byte
0x1-0xC3: __gnu_f2h_internal
0xC3-0xC5: two unknown bytes between those functions (btw what are those?)
0xC5-0x113: __gnu_h2f_internal
0x113-0x115: two unknown bytes between those functions
0x115-0x119: __gnu_f2h_ieee
0x119-0x11D: __gnu_h2f_ieee
0x11D-0x121: __gnu_f2h_alternative
0x121-0x125: __gnu_h2f_alternative // section is only 0x124, what happened to the missing byte?
Notice that the section size is 0x124 and the last function end in 0x125, what happend to the missing byte?
Thanks.
Technically, your "missing byte" is the one right there at 0x0.
Note that you're looking at the value of the symbol, i.e. the runtime function address (this would be a lot clearer if your .text section VMA wasn't 0). Since they're Thumb functions, the addresses have bit 0 set such that the processor will switch to Thumb mode when calling them; the actual locations of those instructions are still halfword-aligned, i.e. 0x0, 0xc4, 0x114, etc. since they couldn't be executed otherwise (you'd take a fault for a misaligned PC). Strip off bit 0 as per what the ARM
ELF spec says about STT_FUNC symbols to get the actual VMA of the instruction corresponding to that symbol, then subtract the start of the section and you should have the same relative offset as within the object file itself.
<offset in section> = (<symbol value> & ~1) - <section VMA>
The extra halfword padding after some functions just ensures each symbol is word-aligned - there are probably various reasons for this, but the first one that comes to mind is that the adr instruction wouldn't work properly if they weren't.

Generating an object file ( .o ) for a linker [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I want to create a c program that creates .o files for the linker on my computer (ld). Gcc does this when I do the command gcc -c myfile.c. Are there any resources that show how to make an object file for a linker?
In order to create a file similar to a file produced by gcc -c, it is important to first understand the format of the file produced.
First, create a file with gcc, and then see if it's format can be reverse-engineered. I will use the following C program (hello.c) to perform this task:
#include <stdio.h>
int main(void)
{
printf("Hello world\n");
return(0);
}
Now, compile the file without linking it:
gcc -Wall -c -o hello.o hello.c
The above code will create hello.o from hello.c. This file is compiled, but not yet linked.
Many files today contain bytes in the header of the file that help identify its format. These identifying bytes are termed 'file magic'. Google 'file magic' and you can find details on how to identify may types of files.
To identify this file type, look for a magic number in the first few lines of a hexdump of the file:
> hexdump -Cn 64 hello.o
00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 |.ELF............|
00000010 02 00 3e 00 01 00 00 00 50 04 40 00 00 00 00 00 |..>.....P.#.....|
00000020 40 00 00 00 00 00 00 00 18 1a 00 00 00 00 00 00 |#...............|
00000030 00 00 00 00 40 00 38 00 09 00 40 00 2a 00 27 00 |....#.8...#.*.'.|
00000040
The identity of the file's format is revealed, in this case, by the first few bytes of the file; 45 4c 46 = ELF. Hence, the output of gcc -c is a file in the ElF format.
Hence, in order to create similar output from a C program, an understanding of the ELF file format is required.
Many *nix systems include a program called readelf that will translate the contents of an ELF file. For example:
> readelf -a hello.o
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x400450
Start of program headers: 64 (bytes into file)
Start of section headers: 6680 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 9
Size of section headers: 64 (bytes)
Number of section headers: 42
Section header string table index: 39
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .interp PROGBITS 0000000000400238 00000238
000000000000001c 0000000000000000 A 0 0 1
[ 2] .note.ABI-tag NOTE 0000000000400254 00000254
0000000000000020 0000000000000000 A 0 0 4
[ 3] .note.SuSE NOTE 0000000000400274 00000274
0000000000000018 0000000000000000 A 0 0 4
[ 4] .note.gnu.build-i NOTE 000000000040028c 0000028c
0000000000000024 0000000000000000 A 0 0 4
[ 5] .hash HASH 00000000004002b0 000002b0
0000000000000024 0000000000000004 A 7 0 8
[ 6] .gnu.hash GNU_HASH 00000000004002d8 000002d8
000000000000001c 0000000000000000 A 7 0 8
[ 7] .dynsym DYNSYM 00000000004002f8 000002f8
0000000000000060 0000000000000018 A 8 1 8
[ 8] .dynstr STRTAB 0000000000400358 00000358
000000000000003d 0000000000000000 A 0 0 1
[ 9] .gnu.version VERSYM 0000000000400396 00000396
0000000000000008 0000000000000002 A 7 0 2
[10] .gnu.version_r VERNEED 00000000004003a0 000003a0
0000000000000020 0000000000000000 A 8 1 8
[11] .rela.dyn RELA 00000000004003c0 000003c0
0000000000000018 0000000000000018 A 7 0 8
[12] .rela.plt RELA 00000000004003d8 000003d8
0000000000000030 0000000000000018 A 7 14 8
[13] .init PROGBITS 0000000000400408 00000408
0000000000000018 0000000000000000 AX 0 0 4
[14] .plt PROGBITS 0000000000400420 00000420
0000000000000030 0000000000000010 AX 0 0 16
[15] .text PROGBITS 0000000000400450 00000450
00000000000001e8 0000000000000000 AX 0 0 16
[16] .fini PROGBITS 0000000000400638 00000638
0000000000000016 0000000000000000 AX 0 0 4
[17] .rodata PROGBITS 0000000000400650 00000650
0000000000000010 0000000000000000 A 0 0 4
[18] .eh_frame_hdr PROGBITS 0000000000400660 00000660
0000000000000034 0000000000000000 A 0 0 4
[19] .eh_frame PROGBITS 0000000000400698 00000698
00000000000000dc 0000000000000000 A 0 0 8
[20] .ctors PROGBITS 0000000000600e30 00000e30
0000000000000010 0000000000000000 WA 0 0 8
[21] .dtors PROGBITS 0000000000600e40 00000e40
0000000000000010 0000000000000000 WA 0 0 8
[22] .jcr PROGBITS 0000000000600e50 00000e50
0000000000000008 0000000000000000 WA 0 0 8
[23] .dynamic DYNAMIC 0000000000600e58 00000e58
00000000000001a0 0000000000000010 WA 8 0 8
[24] .got PROGBITS 0000000000600ff8 00000ff8
0000000000000008 0000000000000008 WA 0 0 8
[25] .got.plt PROGBITS 0000000000601000 00001000
0000000000000028 0000000000000008 WA 0 0 8
[26] .data PROGBITS 0000000000601028 00001028
0000000000000010 0000000000000000 WA 0 0 8
[27] .bss NOBITS 0000000000601038 00001038
0000000000000010 0000000000000000 WA 0 0 8
[28] .comment PROGBITS 0000000000000000 00001038
0000000000000039 0000000000000001 MS 0 0 1
[29] .comment.SUSE.OPT PROGBITS 0000000000000000 00001071
0000000000000006 0000000000000001 MS 0 0 1
[30] .debug_aranges PROGBITS 0000000000000000 00001080
0000000000000060 0000000000000000 0 0 16
[31] .debug_pubnames PROGBITS 0000000000000000 000010e0
000000000000005f 0000000000000000 0 0 1
[32] .debug_info PROGBITS 0000000000000000 0000113f
0000000000000232 0000000000000000 0 0 1
[33] .debug_abbrev PROGBITS 0000000000000000 00001371
0000000000000133 0000000000000000 0 0 1
[34] .debug_line PROGBITS 0000000000000000 000014a4
000000000000011e 0000000000000000 0 0 1
[35] .debug_frame PROGBITS 0000000000000000 000015c8
0000000000000058 0000000000000000 0 0 8
[36] .debug_str PROGBITS 0000000000000000 00001620
0000000000000115 0000000000000001 MS 0 0 1
[37] .debug_loc PROGBITS 0000000000000000 00001735
00000000000000fe 0000000000000000 0 0 1
[38] .debug_ranges PROGBITS 0000000000000000 00001833
0000000000000050 0000000000000000 0 0 1
[39] .shstrtab STRTAB 0000000000000000 00001883
0000000000000192 0000000000000000 0 0 1
[40] .symtab SYMTAB 0000000000000000 00002498
00000000000007c8 0000000000000018 41 65 8
[41] .strtab STRTAB 0000000000000000 00002c60
0000000000000244 0000000000000000 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), l (large)
I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
O (extra OS processing required) o (OS specific), p (processor specific)
There are no section groups in this file.
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
PHDR 0x0000000000000040 0x0000000000400040 0x0000000000400040
0x00000000000001f8 0x00000000000001f8 R E 8
INTERP 0x0000000000000238 0x0000000000400238 0x0000000000400238
0x000000000000001c 0x000000000000001c R 1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000
0x0000000000000774 0x0000000000000774 R E 200000
LOAD 0x0000000000000e30 0x0000000000600e30 0x0000000000600e30
0x0000000000000208 0x0000000000000218 RW 200000
DYNAMIC 0x0000000000000e58 0x0000000000600e58 0x0000000000600e58
0x00000000000001a0 0x00000000000001a0 RW 8
NOTE 0x0000000000000254 0x0000000000400254 0x0000000000400254
0x000000000000005c 0x000000000000005c R 4
GNU_EH_FRAME 0x0000000000000660 0x0000000000400660 0x0000000000400660
0x0000000000000034 0x0000000000000034 R 4
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RW 8
GNU_RELRO 0x0000000000000e30 0x0000000000600e30 0x0000000000600e30
0x00000000000001d0 0x00000000000001d0 R 1
Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .interp .note.ABI-tag .note.SuSE .note.gnu.build-id .hash .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame
03 .ctors .dtors .jcr .dynamic .got .got.plt .data .bss
04 .dynamic
05 .note.ABI-tag .note.SuSE .note.gnu.build-id
06 .eh_frame_hdr
07
08 .ctors .dtors .jcr .dynamic .got
Dynamic section at offset 0xe58 contains 21 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000c (INIT) 0x400408
0x000000000000000d (FINI) 0x400638
0x0000000000000004 (HASH) 0x4002b0
0x000000006ffffef5 (GNU_HASH) 0x4002d8
0x0000000000000005 (STRTAB) 0x400358
0x0000000000000006 (SYMTAB) 0x4002f8
0x000000000000000a (STRSZ) 61 (bytes)
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000015 (DEBUG) 0x0
0x0000000000000003 (PLTGOT) 0x601000
0x0000000000000002 (PLTRELSZ) 48 (bytes)
0x0000000000000014 (PLTREL) RELA
0x0000000000000017 (JMPREL) 0x4003d8
0x0000000000000007 (RELA) 0x4003c0
0x0000000000000008 (RELASZ) 24 (bytes)
0x0000000000000009 (RELAENT) 24 (bytes)
0x000000006ffffffe (VERNEED) 0x4003a0
0x000000006fffffff (VERNEEDNUM) 1
0x000000006ffffff0 (VERSYM) 0x400396
0x0000000000000000 (NULL) 0x0
Relocation section '.rela.dyn' at offset 0x3c0 contains 1 entries:
Offset Info Type Sym. Value Sym. Name + Addend
000000600ff8 000300000006 R_X86_64_GLOB_DAT 0000000000000000 __gmon_start__ + 0
Relocation section '.rela.plt' at offset 0x3d8 contains 2 entries:
Offset Info Type Sym. Value Sym. Name + Addend
000000601018 000100000007 R_X86_64_JUMP_SLO 0000000000000000 puts + 0
000000601020 000200000007 R_X86_64_JUMP_SLO 0000000000000000 __libc_start_main + 0
The decoding of unwind sections for machine type Advanced Micro Devices X86-64 is not currently supported.
Symbol table '.dynsym' contains 4 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND puts#GLIBC_2.2.5 (2)
2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main#GLIBC_2.2.5 (2)
3: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
Symbol table '.symtab' contains 83 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000400238 0 SECTION LOCAL DEFAULT 1
2: 0000000000400254 0 SECTION LOCAL DEFAULT 2
3: 0000000000400274 0 SECTION LOCAL DEFAULT 3
4: 000000000040028c 0 SECTION LOCAL DEFAULT 4
5: 00000000004002b0 0 SECTION LOCAL DEFAULT 5
6: 00000000004002d8 0 SECTION LOCAL DEFAULT 6
7: 00000000004002f8 0 SECTION LOCAL DEFAULT 7
8: 0000000000400358 0 SECTION LOCAL DEFAULT 8
9: 0000000000400396 0 SECTION LOCAL DEFAULT 9
10: 00000000004003a0 0 SECTION LOCAL DEFAULT 10
11: 00000000004003c0 0 SECTION LOCAL DEFAULT 11
12: 00000000004003d8 0 SECTION LOCAL DEFAULT 12
13: 0000000000400408 0 SECTION LOCAL DEFAULT 13
14: 0000000000400420 0 SECTION LOCAL DEFAULT 14
15: 0000000000400450 0 SECTION LOCAL DEFAULT 15
16: 0000000000400638 0 SECTION LOCAL DEFAULT 16
17: 0000000000400650 0 SECTION LOCAL DEFAULT 17
18: 0000000000400660 0 SECTION LOCAL DEFAULT 18
19: 0000000000400698 0 SECTION LOCAL DEFAULT 19
20: 0000000000600e30 0 SECTION LOCAL DEFAULT 20
21: 0000000000600e40 0 SECTION LOCAL DEFAULT 21
22: 0000000000600e50 0 SECTION LOCAL DEFAULT 22
23: 0000000000600e58 0 SECTION LOCAL DEFAULT 23
24: 0000000000600ff8 0 SECTION LOCAL DEFAULT 24
25: 0000000000601000 0 SECTION LOCAL DEFAULT 25
26: 0000000000601028 0 SECTION LOCAL DEFAULT 26
27: 0000000000601038 0 SECTION LOCAL DEFAULT 27
28: 0000000000000000 0 SECTION LOCAL DEFAULT 28
29: 0000000000000000 0 SECTION LOCAL DEFAULT 29
30: 0000000000000000 0 SECTION LOCAL DEFAULT 30
31: 0000000000000000 0 SECTION LOCAL DEFAULT 31
32: 0000000000000000 0 SECTION LOCAL DEFAULT 32
33: 0000000000000000 0 SECTION LOCAL DEFAULT 33
34: 0000000000000000 0 SECTION LOCAL DEFAULT 34
35: 0000000000000000 0 SECTION LOCAL DEFAULT 35
36: 0000000000000000 0 SECTION LOCAL DEFAULT 36
37: 0000000000000000 0 SECTION LOCAL DEFAULT 37
38: 0000000000000000 0 SECTION LOCAL DEFAULT 38
39: 0000000000000000 0 FILE LOCAL DEFAULT ABS init.c
40: 0000000000000000 0 FILE LOCAL DEFAULT ABS
41: 0000000000000000 0 FILE LOCAL DEFAULT ABS initfini.c
42: 000000000040047c 0 FUNC LOCAL DEFAULT 15 call_gmon_start
43: 0000000000400648 0 NOTYPE LOCAL DEFAULT 16 _real_fini
44: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
45: 0000000000600e30 0 OBJECT LOCAL DEFAULT 20 __CTOR_LIST__
46: 0000000000600e40 0 OBJECT LOCAL DEFAULT 21 __DTOR_LIST__
47: 0000000000600e50 0 OBJECT LOCAL DEFAULT 22 __JCR_LIST__
48: 00000000004004a0 0 FUNC LOCAL DEFAULT 15 __do_global_dtors_aux
49: 0000000000601038 1 OBJECT LOCAL DEFAULT 27 completed.6159
50: 0000000000601040 8 OBJECT LOCAL DEFAULT 27 dtor_idx.6161
51: 0000000000400510 0 FUNC LOCAL DEFAULT 15 frame_dummy
52: 0000000000000000 0 FILE LOCAL DEFAULT ABS crtstuff.c
53: 0000000000600e38 0 OBJECT LOCAL DEFAULT 20 __CTOR_END__
54: 0000000000400770 0 OBJECT LOCAL DEFAULT 19 __FRAME_END__
55: 0000000000600e50 0 OBJECT LOCAL DEFAULT 22 __JCR_END__
56: 0000000000400600 0 FUNC LOCAL DEFAULT 15 __do_global_ctors_aux
57: 0000000000000000 0 FILE LOCAL DEFAULT ABS initfini.c
58: 0000000000000000 0 FILE LOCAL DEFAULT ABS 24173361_generating-an-ob
59: 0000000000000000 0 FILE LOCAL DEFAULT ABS elf-init.c
60: 0000000000000000 0 FILE LOCAL DEFAULT ABS
61: 0000000000600e2c 0 NOTYPE LOCAL DEFAULT 20 __init_array_end
62: 0000000000600e58 0 OBJECT LOCAL DEFAULT 23 _DYNAMIC
63: 0000000000600e2c 0 NOTYPE LOCAL DEFAULT 20 __init_array_start
64: 0000000000601000 0 OBJECT LOCAL DEFAULT 25 _GLOBAL_OFFSET_TABLE_
65: 0000000000400560 2 FUNC GLOBAL DEFAULT 15 __libc_csu_fini
66: 0000000000601028 0 NOTYPE WEAK DEFAULT 26 data_start
67: 0000000000000000 0 FUNC GLOBAL DEFAULT UND puts##GLIBC_2.2.5
68: 0000000000601038 0 NOTYPE GLOBAL DEFAULT 26 _edata
69: 0000000000400638 16 FUNC GLOBAL DEFAULT 16 _fini
70: 0000000000600e48 0 OBJECT GLOBAL HIDDEN 21 __DTOR_END__
71: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main##GLIBC_
72: 0000000000601028 0 NOTYPE GLOBAL DEFAULT 26 __data_start
73: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
74: 0000000000601030 0 OBJECT GLOBAL HIDDEN 26 __dso_handle
75: 0000000000400650 4 OBJECT GLOBAL DEFAULT 17 _IO_stdin_used
76: 0000000000400570 137 FUNC GLOBAL DEFAULT 15 __libc_csu_init
77: 0000000000601048 0 NOTYPE GLOBAL DEFAULT 27 _end
78: 0000000000400450 0 FUNC GLOBAL DEFAULT 15 _start
79: 0000000000601038 0 NOTYPE GLOBAL DEFAULT 27 __bss_start
80: 000000000040053c 21 FUNC GLOBAL DEFAULT 15 main
81: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses
82: 0000000000400408 0 FUNC GLOBAL DEFAULT 13 _init
Histogram for bucket list length (total of 3 buckets):
Length Number % of total Coverage
0 1 ( 33.3%)
1 1 ( 33.3%) 33.3%
2 1 ( 33.3%) 100.0%
Version symbols section '.gnu.version' contains 4 entries:
Addr: 0000000000400396 Offset: 0x000396 Link: 7 (.dynsym)
000: 0 (*local*) 2 (GLIBC_2.2.5) 2 (GLIBC_2.2.5) 0 (*local*)
Version needs section '.gnu.version_r' contains 1 entries:
Addr: 0x00000000004003a0 Offset: 0x0003a0 Link: 8 (.dynstr)
000000: Version: 1 File: libc.so.6 Cnt: 1
0x0010: Name: GLIBC_2.2.5 Flags: none Version: 2
Notes at offset 0x00000254 with length 0x00000020:
Owner Data size Description
GNU 0x00000010 NT_GNU_ABI_TAG (ABI version tag)
OS: Linux, ABI: 2.6.4
Notes at offset 0x00000274 with length 0x00000018:
Owner Data size Description
SuSE 0x00000004 Unknown note type: (0x45537553)
Notes at offset 0x0000028c with length 0x00000024:
Owner Data size Description
GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring)
Build ID: 710ef458701fed230f91233a227b7b10c024e2ed
While, that is a lot of detail for such a little file. Here is how to break it down problematically. First, the elf(64) header:
typedef struct elf64_hdr {
unsigned char e_ident[EI_NIDENT]; /* ELF "magic number" */
Elf64_Half e_type;
Elf64_Half e_machine;
Elf64_Word e_version;
Elf64_Addr e_entry; /* Entry point virtual address */
Elf64_Off e_phoff; /* Program header table file offset */
Elf64_Off e_shoff; /* Section header table file offset */
Elf64_Word e_flags;
Elf64_Half e_ehsize;
Elf64_Half e_phentsize;
Elf64_Half e_phnum;
Elf64_Half e_shentsize;
Elf64_Half e_shnum;
Elf64_Half e_shstrndx;
} Elf64_Ehdr;
The secret to creating an elf file is to understand the above structure. This is the first bit of the file your C program must write. Although too lengthy to detail here, you can find this structure in elf.h; which is located (on most Linux systems) here: /usr/include/elf.h.

Converting ARM to C

Given, for example, the following ARM assembly code, are there any straightforward ways to convert it directly to C, using whatever appropriate variable names?
ADD $2 $0 #9
ADD $3 $0 #3
ADD $1 $0 $0
loop: ADD $1 $1 #1
ADD $3 $0 $3, LSL #1
SUB $2 $2 $1
CMP $2 $1
BNE loop
Also, as I'm still learning ARM, how many times will the loop execute say, SUB or ADD? Are there straightforward ways to determine this?
Thanks for the help! Any other insight not particularly aimed at answering the question would also be great.
In short, BNE - Branch Not Equal, could suggest either a do{...}while loop or the other way while (...){...}, even possibly a for( ...; ... < ....; ...){...} loop, that's about far as it can go.
As for reading the addition/subtraction from some registers (read, memory variables in the context of C), you will have to play by reading it and come up with a near equivalent.
A decompiler may not help you at this stage, play with a couple of C code to practice and compile it to assembler language using the -S command parameter passed to the C compiler and see what you get, mostly trial and error am afraid, that is, if you're looking for the exact replica of that code in the above question.
unsigned int r0,r1,r2,r3;
r2=r0+9;
r3=r0+3;
r1=r0+r0;
do
{
r1=r1+1;
r3=r0+(r3<<1);
r2=r2-r1;
} while(r2!=r1);
not knowing what r0 is going in the loop can happen a few times or many times (like millions? billions?) r2 is decreasing, r1 is increasing if they dont collide with an equals the first time they pass they will have to roll around. every loop r1 gets bigger so r2 gets smaller that much faster. should be very easy to add a printf and some test values for r0 and see what happens.
say for example r0 is a 0 before entering this code. r2 is r0+9 = 9; and r1 is double r0 which is 0.
The first so many loops would go like this with the four variables r0,r1,r2,r3
00000000 00000001 00000008 00000006
00000000 00000002 00000007 0000000C
00000000 00000003 00000006 00000018
00000000 00000004 00000005 00000030
00000000 00000005 00000004 00000060
00000000 00000006 00000003 000000C0
00000000 00000007 00000002 00000180
00000000 00000008 00000001 00000300
00000000 00000009 00000000 00000600
00000000 0000000A FFFFFFFF 00000C00
00000000 0000000B FFFFFFFE 00001800
r2 and r1 are not going to collide.
but if r0 was a 1 going in then
00000001 00000003 00000009 00000009
00000001 00000004 00000008 00000013
00000001 00000005 00000007 00000027
00000001 00000006 00000006 0000004F
r0 = 3
00000003 00000007 0000000B 0000000F
00000003 00000008 0000000A 00000021
00000003 00000009 00000009 00000045
r0 needs to be odd so far. but when you make r0 a 9 then
00000009 00000013 00000011 00000021
00000009 00000014 00000010 0000004B
00000009 00000015 0000000F 0000009F
00000009 00000016 0000000E 00000147
00000009 00000017 0000000D 00000297
00000009 00000018 0000000C 00000537
00000009 00000019 0000000B 00000A77
00000009 0000001A 0000000A 000014F7
00000009 0000001B 00000009 000029F7
00000009 0000001C 00000008 000053F7
00000009 0000001D 00000007 0000A7F7
00000009 0000001E 00000006 00014FF7
00000009 0000001F 00000005 00029FF7
00000009 00000020 00000004 00053FF7
00000009 00000021 00000003 000A7FF7
00000009 00000022 00000002 0014FFF7
00000009 00000023 00000001 0029FFF7
00000009 00000024 00000000 0053FFF7
00000009 00000025 FFFFFFFF 00A7FFF7
00000009 00000026 FFFFFFFE 014FFFF7
basically it is a little deterministic with some rules, but if the comparison doesnt happen then the loop may run forever or at least many many cycles.

Resources