├── .gitignore
├── AUTHOR.txt
├── BUGS.txt
├── LICENSE.txt
├── README.txt
├── TODO.txt
├── jni
├── Android.mk
├── Application.mk
└── src
│ ├── banner.h
│ ├── env1.c
│ ├── env2.c
│ ├── env3.c
│ ├── fuzz_dyn.c
│ ├── fuzz_hdr.c
│ ├── fuzz_note.c
│ ├── fuzz_pht.c
│ ├── fuzz_rel.c
│ ├── fuzz_sht.c
│ ├── fuzz_strs.c
│ ├── fuzz_sym.c
│ ├── generators.c
│ ├── lc_elf.h
│ ├── logger.c
│ ├── melkor.c
│ ├── melkor.h
│ ├── numbers.h
│ └── print_envp_vars.c
└── libs
└── armeabi
├── env1
├── env2
├── env3
├── melkor
└── print_envp_vars
/.gitignore:
--------------------------------------------------------------------------------
1 | obj/
2 |
--------------------------------------------------------------------------------
/AUTHOR.txt:
--------------------------------------------------------------------------------
1 | ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
2 | | -- AUTHOR -- |
3 | ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
4 |
5 | | Name: Alejandro Hernandez H. (nitr0us)
6 | | Twitter: http://twitter.com/nitr0usmx
7 | | Email: nitrousenador [at] gmail [dot] com
8 | | Website: http://www.brainoverflow.org
9 | | Blog: http://chatsubo-labs.blogspot.com
10 | | Location:
11 |
12 | .
13 | \'~~~-,
14 | \ '-,_
15 | \ /\ `~'~''\ M E X I C O
16 | _\ \\ \/~\
17 | \__ \\ \
18 | \ \\. \
19 | \ \ \ `~~
20 | '\\ \. /
21 | / \ \ |
22 | \_\ \ | _.----,
23 | | \ ! /
24 | '._ \_ __/ _/
25 | \_ ''--'' __/
26 | \.__ |
27 | ''.__ __.._ o<-_\---- here !
28 | '' './ `
29 |
--------------------------------------------------------------------------------
/BUGS.txt:
--------------------------------------------------------------------------------
1 | ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
2 | | -- BUGS -- |
3 | ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
4 |
5 | - No boundary checkings in the whole codebase. If a malformed ELF is
6 | supplied, it'll definitely segfault.
7 |
8 | It's supposed to be fed with non-malformed ELFs (templates), hence,
9 | you can use it as a test subject too ;-), fuzzing the fuzzer,
10 | meta-fuzzing, inception fuzzing, whatever...
11 |
12 | Bugs (overflows and off-by-one's) while treating strings and pointers
13 | with functions like strncpy(), strcat(), memcpy(), strlen(), etc. etc.
14 |
15 | - The data structures are adapted at compilation time based on the CPU
16 | where Melkor is running by checking the __i386__ and __x86_64__ macros,
17 | not by the ELF file to be used as a template (HDR.e_ident[EI_CLASS]).
18 |
19 | I've been through this before and I solved it by wrapping many data
20 | structures and assignations in macros to automatically adapt them
21 | based on the architecture detected in HDR.e_ident[EI_CLASS]. However,
22 | it adds more complexity to the code. You can see it at:
23 | http://www.brainoverflow.org/code/dissector.c
24 |
25 | So, if you want to fuzz a 32-bit ELF file, you need to compile and run
26 | Melkor in a 32-bit OS, and vice versa for 64-bit files.
27 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 |
635 | Copyright (C)
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | Copyright (C)
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
675 |
--------------------------------------------------------------------------------
/README.txt:
--------------------------------------------------------------------------------
1 | ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
2 | | -- DESCRIPTION -- |
3 | ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
4 |
5 | Melkor - An ELF File Format Fuzzer
6 |
7 | Melkor, a fictional character from J. R. R. Tolkien's Middle-earth
8 | legendarium, was the first Dark Lord and master of Sauron. He's
9 | mentioned briefly in The Lord of the Rings and is known for:
10 |
11 | "... Melkor had captured a number of ELVES before the Valar
12 | attacked him, and he tortured and corrupted them, breeding the
13 | first Orcs." (http://en.wikipedia.org/wiki/Morgoth)
14 |
15 | "... Melkor was cunning and more filled with malice than ever.
16 | Seeing the bliss of the ELVES and remembering that it was for their
17 | sake that he was overthrown, Melkor desired above all things to
18 | corrupt them." (http://lotr.wikia.com/wiki/Melkor)
19 |
20 | "Orcs...This has been so from the day they were bred by Melkor from
21 | corrupted, tortured and mutilated ELVES that may also have been
22 | forced to breed with other unnatural abominations in the dominion
23 | of the Dark Powers." (http://lotr.wikia.com/wiki/Orcs)
24 |
25 | To honor his name, this piece of code takes an ELF, corrupts it and
26 | creates as much Orcs as you want.
27 |
28 | Melkor is a hybrid fuzzer (mutation-based and generation-based).
29 | It mutates the existing data in an ELF sample given to create orcs
30 | (malformed ELFs), however, it doesn't change values randomly (dumb
31 | fuzzing), instead, it fuzzes certain metadata with semi-valid values
32 | through the use of fuzzing rules (knowledge base). Written in C,
33 | Melkor is a very intuitive and easy-to-use fuzzer to find functional
34 | (and security) bugs in ELF parsers.
35 |
36 | The fuzzing rules were designed with the following inputs in mind:
37 | - ELF Specification violations
38 | * TIS ELF Specification 1.2 (May, 1995)
39 | * ELF-64 Object File Format 1.5 (May 1998)
40 | - Misc ideas & considerations
41 | - Parsing patterns in ELF software
42 |
43 | You will find the fuzzing rules in detail and some other schematics
44 | in the docs/ directory.
45 |
46 |
47 |
48 | ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
49 | | -- REQUIREMENTS -- |
50 | ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
51 |
52 | - make
53 | - gcc
54 |
55 |
56 |
57 | ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
58 | | -- COMPILATION & USAGE -- |
59 | ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
60 | The compilation is very straightforward, just type:
61 | $make
62 |
63 | It will create the file 'melkor', which is the fuzzer itself, and
64 | some other ELF files inside the templates/ folder, including normal
65 | ELF files such as a normal ELF executable, some shared libraries,
66 | an static ELF (standalone executable) and some others.
67 |
68 | By running melkor, a list of options will be shown and you will
69 | realize that it's very intuitive and easy-to-use. All you have to
70 | supply is the name of an ELF to be used as a template, which could
71 | be any of the ones inside the templates/ dir.
72 |
73 | Depending on what kind of software you want to test, you have to
74 | choose which metadata you want to fuzz. For example, if you want
75 | to test an OS loader, you probably might want to fuzz only the
76 | Program Header Table (-P) and/or the Dynamic Section (-D). On the
77 | other hand, perhaps you might want to fuzz the Section Header
78 | Table and the ELF Header to test any antivirus engine or debugger.
79 | Fuzzing the Symbols Tables (-s) and/or Relocations Tables (-R) on
80 | relocatable files (.o) or shared libraries (.so) to test compilers
81 | and/or linkers. The String Tables could be fuzzed as well (-Z).
82 | It's up to you to decide how badly you want to corrupt an ELF }:-)
83 |
84 | Once the orcs have been created inside the orcs_*/ dir, it's time
85 | to test them with the help of test_fuzzed.sh, where you can simply
86 | specify the name of the folder with the orcs to be run (OS loader
87 | testing) or add an extra parameter to specify which program (and
88 | its parameters) you'd like to test against every malformed ELF
89 | within the orcs folder. This script has the option to fuzz some
90 | environment variables (defined as fuzzing rules as well).
91 | Showing logs with #dmesg after running the script could be useful
92 | to identify which program/library crashed and where that crash was.
93 | Some examples are shown running the script without parameters.
94 |
95 | If you want test the malformed ELFs (orcs) automatically on Windows
96 | environment, there is included a batch script (win_test_fuzzed.bat)
97 | with almost the same functionality of the script for *NIX.
98 |
99 | Happy Fuzzing !
100 |
101 |
102 | ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
103 | | -- DIRS -- |
104 | ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
105 |
106 | - docs/ Contains related documentation such as the detailed
107 | list of fuzzing rules as well as the list of ELF
108 | metadata dependencies.
109 |
110 | - templates/ It has some ELF files compiled at the same time than
111 | melkor and could be used to feed melkor:
112 | foo.c -> foo.o (ELF object)-> foo (ELF executable)
113 | foo.c -> foo_static (ELF static executable)
114 | libfoo.c -> libfoo.so (ELF shared object)
115 | and some others. Type "$make templ" to see in detail
116 | which other ELF templates are created.
117 |
118 | - orcs_*/ Will contain the malformed ELF files (based on the
119 | given template file) created after the fuzzing process.
120 |
121 | - src/ Melkor source code.
122 |
123 |
124 |
125 | ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
126 | | -- BUGS -- |
127 | ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
128 |
129 | Please read BUGS.txt
130 |
131 |
132 |
133 | ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
134 | | -- CONTACT -- |
135 | ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
136 |
137 | Name: Alejandro Hernandez H. [nitr0us]
138 | Twitter: http://twitter.com/nitr0usmx
139 | Email: nitrousenador [at] gmail [dot] com
140 | Website: http://www.brainoverflow.org
141 | Blog: http://chatsubo-labs.blogspot.com
142 |
143 |
144 |
145 | ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
146 | | -- IN MEMORIAL -- |
147 | ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
148 |
149 | This project is dedicated to the memory of one of my best friends,
150 | Aaron Alba.
151 |
152 |
153 |
154 | ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
155 | | -- LICENSE -- |
156 | ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
157 |
158 | Melkor - An ELF File Format Fuzzer
159 | Copyright (C) 2014 Alejandro Hernandez H. (nitr0us)
160 |
161 | This program is free software: you can redistribute it and/or modify
162 | it under the terms of the GNU General Public License as published by
163 | the Free Software Foundation, either version 3 of the License, or
164 | (at your option) any later version.
165 |
166 | This program is distributed in the hope that it will be useful,
167 | but WITHOUT ANY WARRANTY; without even the implied warranty of
168 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
169 | GNU General Public License for more details.
170 |
171 | You should have received a copy of the GNU General Public License
172 | along with this program. If not, see .
173 |
--------------------------------------------------------------------------------
/TODO.txt:
--------------------------------------------------------------------------------
1 | ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
2 | | -- TODO -- |
3 | ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
4 |
5 | - Fuzz the (symbol) Hash Table(s) (SHT_HASH | SHT_GNU_HASH)
6 | These rules are marked in red in docs/Melkor_Fuzzing_Rules.pdf
7 |
8 | - Fuzz the debug information (DWARF format)
9 | This rule is marked in orange in docs/Melkor_Fuzzing_Rules.pdf
10 | An example of a malformed DWARF payload can be seen at:
11 | http://www.exploit-db.com/exploits/23523/
12 |
13 | - Smart fuzzing of SHT_REL or SHT_RELA based on the relocation scheme used
14 | More info: http://www.mindfruit.co.uk/2012/06/relocations-relocations.html
15 |
16 | - Fuzz uncommon data structs in /usr/include/elf.h such as Elf*_Syminfo,
17 | Elf*_Verdef, etc.
18 |
19 | - Port to *BSD
20 |
--------------------------------------------------------------------------------
/jni/Android.mk:
--------------------------------------------------------------------------------
1 | LOCAL_PATH := $(call my-dir)
2 |
3 | # Build malkor #
4 | include $(CLEAR_VARS)
5 | LOCAL_MODULE := melkor
6 | SRC := src
7 | LOCAL_SRC_FILES := $(SRC)/melkor.c $(SRC)/logger.c \
8 | $(SRC)/fuzz_hdr.c $(SRC)/fuzz_sht.c \
9 | $(SRC)/fuzz_pht.c $(SRC)/fuzz_sym.c \
10 | $(SRC)/fuzz_dyn.c $(SRC)/fuzz_rel.c \
11 | $(SRC)/fuzz_note.c $(SRC)/fuzz_strs.c \
12 | $(SRC)/generators.c
13 |
14 | LOCAL_CFLAGS += -fPIE -ggdb -Wall -Wno-maybe-uninitialized -DDEBUG
15 | LOCAL_LDFLAGS += -fPIE -pie
16 | include $(BUILD_EXECUTABLE)
17 |
18 | # Build envtools #
19 | include $(CLEAR_VARS)
20 | LOCAL_MODULE := env1
21 | SRC := src
22 | LOCAL_SRC_FILES := $(SRC)/env1.c $(SRC)/generators.c
23 |
24 | LOCAL_CFLAGS += -fPIE -ggdb -Wall -DDEBUG
25 | LOCAL_LDFLAGS += -fPIE -pie
26 | include $(BUILD_EXECUTABLE)
27 |
28 | include $(CLEAR_VARS)
29 | LOCAL_MODULE := env2
30 | SRC := src
31 | LOCAL_SRC_FILES := $(SRC)/env2.c $(SRC)/generators.c
32 |
33 | LOCAL_CFLAGS += -fPIE -ggdb -Wall -DDEBUG
34 | LOCAL_LDFLAGS += -fPIE -pie
35 | include $(BUILD_EXECUTABLE)
36 |
37 | include $(CLEAR_VARS)
38 | LOCAL_MODULE := env3
39 | SRC := src
40 | LOCAL_SRC_FILES := $(SRC)/env3.c $(SRC)/generators.c
41 |
42 | LOCAL_CFLAGS += -fPIE -ggdb -Wall -DDEBUG
43 | LOCAL_LDFLAGS += -fPIE -pie
44 | include $(BUILD_EXECUTABLE)
45 |
46 | include $(CLEAR_VARS)
47 | LOCAL_MODULE := print_envp_vars
48 | SRC := src
49 | LOCAL_SRC_FILES := $(SRC)/print_envp_vars.c $(SRC)/generators.c
50 |
51 | LOCAL_CFLAGS += -fPIE -ggdb -Wall -DDEBUG
52 | LOCAL_LDFLAGS += -fPIE -pie
53 | include $(BUILD_EXECUTABLE)
54 |
--------------------------------------------------------------------------------
/jni/Application.mk:
--------------------------------------------------------------------------------
1 | APP_PLATFORM := android-9
2 |
--------------------------------------------------------------------------------
/jni/src/banner.h:
--------------------------------------------------------------------------------
1 | const char *logo =
2 | " | \n"
3 | " | M e l k o R "VERSION" - An ELF File Format Fuzzer \n"
4 | " | by nitr0us \n"
5 | " | \n"
6 | " '. ;' '; .' \n"
7 | " ;l, x, lc ;c' \n"
8 | " ,x; k; ol :o. \n"
9 | " dk. ;0. :0. ,k: \n"
10 | " .0k dO.,;0: .Ok \n"
11 | " .0O. cO: c dO. cOx \n"
12 | " .O0ocOo l .kk;xOd \n"
13 | " .OO00O; . ;O00Ox \n"
14 | " .cxkkkx:xkolkkkxo. \n"
15 | " 'kkkkkkxxxxxx' \n"
16 | " .xxxxxxxxxxxxx. \n"
17 | " .;;:xxxxxxxxxxxxo;;;. \n"
18 | " ..:dxxdo.ddddd:.. \n"
19 | " ddl:. .ldd: \n"
20 | " ldd. .ddl \n"
21 | " .cdlc. .ldc. \n"
22 | " :o. .o: \n"
23 | " ; ; \n";
24 |
25 |
26 | const char *banners[] = {
27 | " \n"
28 | " .-. . . _ .-. \n"
29 | " .-. /|/| / / _ (_) )-. .-. \n"
30 | " `-' / ` | .-. / /-./ .-._. / \\ `-' \n"
31 | " .-. / | ./--'_ / / ) ( ) / ) .-. \n"
32 | " `-' .-' / | (__.' /_.- _/ \\ `-' .-/ `--' `-' \n"
33 | " (__.' `. (_/ `. \n"
34 | " `._) `._) \n",
35 |
36 |
37 | " ___ ___ ____ __ __ __ ___ ____ \n"
38 | " ||\\\\//|| || || || // // \\\\ || \\\\ \n"
39 | " << || \\/ || ||== || ||<< (( )) ||_// >>\n"
40 | " || || ||___ ||__| || \\\\ \\\\_// || \\\\ \n",
41 |
42 |
43 | "____ ___ ___ _ _ ______ ____ \n"
44 | "\\ \\ \\ _ | \\/ | | | | | | ___ \\ _ / / / \n"
45 | " \\ \\ \\ |_| | . . | ___ | | | | __ ___ | |_/ / |_| / / / \n"
46 | " \\ \\ \\ | |\\/| | / _ \\ | | | |/ / / _ \\ | / / / / \n"
47 | " \\ \\ \\ _ | | | | | __/ | | | < | (_) | | |\\ \\ _ / / / \n"
48 | " \\_\\_\\ |_| \\_| |_/ \\___| |_| |_|\\_\\ \\___/ \\_| \\_| |_| /_/_/ \n",
49 |
50 |
51 | "/\\/\\ _____ __ __ __________ /\\/\\ \n"
52 | "\\ \\ \\ / \\ ____ | | | | __ ____ \\______ \\ / / / \n"
53 | " \\ \\ \\ / \\ / \\ _/ __ \\ | | | |/ / / _ \\ | _/ / / / \n"
54 | " \\ \\ \\ / Y \\ \\ ___/ | |__ | < ( <_> ) | | \\ / / / \n"
55 | " \\ \\ \\ \\____|__ / \\___ > |____/ |__|_ \\ \\____/ |____|_ / / / / \n"
56 | " \\/\\/ \\/ \\/ \\/ \\/ \\/\\/ \n",
57 |
58 |
59 | "::: _______ _______ _ _ _____ ______ ::: \n"
60 | "::: | | | |______ | |____/ | | |_____/ ::: \n"
61 | "::: | | | |______ |_____ | \\_ |_____| | \\_ ::: \n"
62 | };
63 |
64 | const char *elf_ascii[] = {
65 | " ..-.--.. \n"
66 | " ,','.-`.-.`. \n"
67 | " :.',;' `.\\. \n",
68 | " ||//----,-.--\\| <<--- %s\n",
69 | " \\`:|/-----`-'--||'/ \n"
70 | " \\\\|: |:' \n"
71 | " `|| \" \\ |! _________________________________\n",
72 | " |!| ;| / I'll be corrupted %5d times ! \\ \n",
73 | " !||:. -- /|! \\_________________________________/ \n"
74 | " /||!||:.___.|!||\\ \n"
75 | " /|!|||!| |!||!\\\\:. \n"
76 | " ,'//!||!||!`._.||!||,:\\\\\\\n"
77 | ": :: |!|||!| |!||! |!::\n"
78 | "| |! !||!|||`---!|!|| ||!|\n\n"
79 | };
80 |
--------------------------------------------------------------------------------
/jni/src/env1.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Melkor - An ELF File Format Fuzzer
3 | * Copyright (C) 2014 Alejandro Hernandez H. (nitr0us)
4 | *
5 | * Mexico
6 | */
7 |
8 | #include "melkor.h"
9 |
10 | int main()
11 | {
12 | char *env_LD_BIND_NOW;
13 |
14 | srand(getseed());
15 |
16 | if(rand() % 2){
17 | int r = rand();
18 |
19 | if(r % 3 == 0)
20 | env_LD_BIND_NOW = "1";
21 | else if(r % 3 == 1)
22 | env_LD_BIND_NOW = "on";
23 | else
24 | env_LD_BIND_NOW = "off";
25 | } else {
26 | unsigned short s = 8 + (rand() % 1024);
27 | unsigned short ndx = 0;
28 |
29 | env_LD_BIND_NOW = malloc(s);
30 |
31 | while(ndx < s)
32 | *(env_LD_BIND_NOW + ndx++) = 'A' + (rand() % ('Z' - 'A')); // Range of printable chars 'A'-'Z'
33 | }
34 |
35 | printf("%s", env_LD_BIND_NOW);
36 |
37 | return 0;
38 | }
39 |
--------------------------------------------------------------------------------
/jni/src/env2.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Melkor - An ELF File Format Fuzzer
3 | * Copyright (C) 2014 Alejandro Hernandez H. (nitr0us)
4 | *
5 | * Mexico
6 | */
7 |
8 | #include "melkor.h"
9 |
10 | #define BUFF_SIZE 2048
11 |
12 | int main(int argc, char *argv[], char *envp[])
13 | {
14 | unsigned short cnt = 0, ndx;
15 | char *env_PATH, *path, env_paths[13][37]; // Only 13 paths taken from $PATH with 37 chars each one, enough to play with ...
16 | char *env_LD_LIBRARY_PATH = malloc(BUFF_SIZE); // Yeah yeah, I prefer to spend time writing this comment than checking the returned value by malloc() :D
17 | char *fuzzed_path;
18 |
19 | // Split $PATH
20 | env_PATH = getenv("PATH");
21 |
22 | path = strtok(env_PATH, ":");
23 | strncpy(env_paths[cnt], path, 37);
24 | env_paths[cnt++][36] = '\0';
25 |
26 | while((path = strtok(NULL, ":")) != NULL && cnt < 13){
27 | strncpy(env_paths[cnt], path, 37);
28 | env_paths[cnt++][36] = '\0';
29 | }
30 | // Split
31 |
32 | srand(getseed());
33 |
34 | // Overflows and off-by-one's section :D, exploit them !
35 | *env_LD_LIBRARY_PATH = '\0';
36 | while(strlen(env_LD_LIBRARY_PATH) < BUFF_SIZE){
37 | if(rand() % 4 < 3){ // 75% chance of valid paths
38 | ndx = rand() % cnt;
39 | if(strlen(env_LD_LIBRARY_PATH) + strlen(env_paths[ndx]) < BUFF_SIZE)
40 | strcat(env_LD_LIBRARY_PATH, env_paths[ndx]);
41 | else
42 | break;
43 | } else {
44 | fuzzed_path = get_fuzzed_path();
45 |
46 | if(strlen(env_LD_LIBRARY_PATH) + strlen(fuzzed_path) < BUFF_SIZE)
47 | strcat(env_LD_LIBRARY_PATH, fuzzed_path);
48 | else
49 | break;
50 | }
51 |
52 | if(strlen(env_LD_LIBRARY_PATH) + 1 < BUFF_SIZE)
53 | strcat(env_LD_LIBRARY_PATH, ":");
54 |
55 | if(strlen(env_LD_LIBRARY_PATH) == BUFF_SIZE - 1)
56 | break;
57 | }
58 |
59 | printf("%s", env_LD_LIBRARY_PATH);
60 |
61 | free(env_LD_LIBRARY_PATH);
62 |
63 | return 0;
64 | }
65 |
--------------------------------------------------------------------------------
/jni/src/env3.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Melkor - An ELF File Format Fuzzer
3 | * Copyright (C) 2014 Alejandro Hernandez H. (nitr0us)
4 | *
5 | * Mexico
6 | */
7 |
8 | #include "melkor.h"
9 |
10 | #define BUFF_SIZE 1024
11 |
12 | static char *fuzz_paths[] = {
13 | "orcs_libfoo.so/",
14 | "../orcs_libfoo.so/",
15 | "./..../",
16 | ";/;;/",
17 | "/.so/",
18 | "~~//",
19 | "\\",
20 | "$/",
21 | };
22 |
23 | int main(int argc, char *argv[], char *envp[])
24 | {
25 | unsigned short ndx;
26 | char orcfname[strlen("orc_") + 16];
27 | char *env_LD_PRELOAD = malloc(BUFF_SIZE); // Yeah yeah, I prefer to spend time writing this comment than checking the returned value by malloc() :D
28 |
29 | srand(getseed());
30 |
31 | // Overflows and off-by-one's section :D, exploit them !
32 | *env_LD_PRELOAD = '\0';
33 | while(strlen(env_LD_PRELOAD) < BUFF_SIZE){
34 | if(rand() % 2){
35 | ndx = rand() % 2; // First two entries. Valid paths to ../orcs_libfoo.so/ in case libfoo.so has been already fuzzed
36 | if(strlen(env_LD_PRELOAD) + strlen(fuzz_paths[ndx]) < BUFF_SIZE)
37 | strcat(env_LD_PRELOAD, fuzz_paths[ndx]);
38 | else
39 | break;
40 | } else {
41 | ndx = 2 + (rand() % (sizeof(fuzz_paths) / sizeof(char *)) - 2);
42 | if(strlen(env_LD_PRELOAD) + strlen(fuzz_paths[ndx]) < BUFF_SIZE)
43 | strcat(env_LD_PRELOAD, fuzz_paths[ndx]);
44 | else
45 | break;
46 | }
47 |
48 | snprintf(orcfname, sizeof(orcfname), "orc_%.4d.so", 1 + rand() % 100);
49 | if(strlen(env_LD_PRELOAD) + strlen(orcfname) < BUFF_SIZE)
50 | strcat(env_LD_PRELOAD, orcfname);
51 | else
52 | break;
53 |
54 | if(rand() % 10 < 1) // Double .so extension
55 | if(strlen(env_LD_PRELOAD) + 3 < BUFF_SIZE)
56 | strcat(env_LD_PRELOAD, ".so");
57 |
58 | if(strlen(env_LD_PRELOAD) + 1 < BUFF_SIZE)
59 | strcat(env_LD_PRELOAD, ":");
60 |
61 | if(strlen(env_LD_PRELOAD) == BUFF_SIZE - 1)
62 | break;
63 | }
64 |
65 | printf("%s", env_LD_PRELOAD);
66 |
67 | free(env_LD_PRELOAD);
68 |
69 | return 0;
70 | }
71 |
--------------------------------------------------------------------------------
/jni/src/fuzz_dyn.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Melkor - An ELF File Format Fuzzer
3 | * Copyright (C) 2014 Alejandro Hernandez H. (nitr0us)
4 | *
5 | * Mexico
6 | */
7 |
8 | #include "melkor.h"
9 |
10 | #define N_RULES_DYN 18 // Total of fuzzing rules defined for this metadata type
11 |
12 | // Array of function pointers. Index zero won't be used. The fuzzing rules start from index 1
13 | func_ptr dyn[N_RULES_DYN + 1];
14 |
15 | void initialize_dyn_funcs(void) __attribute__((constructor));
16 |
17 | /* External vars */
18 | extern FILE *logfp;
19 | extern unsigned int quiet;
20 | extern unsigned int like_a, like_b;
21 | extern unsigned int secnum;
22 | extern unsigned int entry;
23 | extern char *orcptr;
24 | extern Elf_Ehdr *orcHDR;
25 | extern Elf_Shdr *elfSHT, *orcSHT;
26 | extern Elf_Dyn *elfDYN, *orcDYN;
27 | extern Elf_Dyn *elfOrigDYN;
28 | extern Elf_Off linkstrtab_offset;
29 |
30 | void fuzz_dyn()
31 | {
32 | int rule;
33 |
34 | for(rule = 1; rule <= N_RULES_DYN; rule++)
35 | if((rand() % like_a) < like_b)
36 | if(dyn[rule]()){
37 | printf(". ");
38 | debug("SHT[%d] DYN[%d] rule [%.2d] executed\n", secnum, entry, rule);
39 | fprintf(logfp, " | SHT[%d] DYN[%d] rule [%.2d] executed\n", secnum, entry, rule);
40 | }
41 | }
42 |
43 | int dyn1(void)
44 | {
45 | if(orcDYN->d_tag != DT_NEEDED &&
46 | orcDYN->d_tag != DT_SONAME &&
47 | orcDYN->d_tag != DT_RPATH)
48 | return 0;
49 |
50 | if(rand() % 3 == 0)
51 | return 0;
52 |
53 | orcDYN->d_un.d_val = rand() & 0x0fff; // 12-bit random offset
54 |
55 | fprintf(logfp, "(DYN[%d]->d_un.d_val = 0x"HEX")", entry, orcDYN->d_un.d_val);
56 |
57 | return 1;
58 | }
59 |
60 | int dyn2(void)
61 | {
62 | if(orcDYN->d_tag != DT_PLTRELSZ &&
63 | orcDYN->d_tag != DT_RELSZ &&
64 | orcDYN->d_tag != DT_RELASZ &&
65 | orcDYN->d_tag != DT_STRSZ)
66 | return 0;
67 |
68 | if(rand() % 2)
69 | return 0;
70 |
71 | int r = rand();
72 |
73 | if(r % 4 < 2) // 50% chance
74 | orcDYN->d_un.d_val = rand() & 0xff;
75 | else if(r % 4 == 2)
76 | orcDYN->d_un.d_val = getElf_Word();
77 | else
78 | orcDYN->d_un.d_val = 0x00;
79 |
80 | fprintf(logfp, "(DYN[%d]->d_un.d_val = 0x"HEX")", entry, orcDYN->d_un.d_val);
81 |
82 | return 1;
83 | }
84 |
85 | int dyn3(void)
86 | {
87 | if(orcDYN->d_tag != DT_RELENT &&
88 | orcDYN->d_tag != DT_RELAENT &&
89 | orcDYN->d_tag != DT_SYMENT)
90 | return 0;
91 |
92 | if(rand() % 2)
93 | return 0;
94 |
95 | int r = rand();
96 |
97 | if(r % 4 < 2) // 50% chance
98 | orcDYN->d_un.d_val = rand() & 0xff;
99 | else if(r % 4 == 2)
100 | orcDYN->d_un.d_val = getElf_Word();
101 | else
102 | orcDYN->d_un.d_val = 0x00;
103 |
104 | fprintf(logfp, "(DYN[%d]->d_un.d_val = 0x"HEX")", entry, orcDYN->d_un.d_val);
105 |
106 | return 1;
107 | }
108 |
109 | int dyn4(void)
110 | {
111 | if(orcDYN->d_tag != DT_PLTGOT)
112 | return 0;
113 |
114 | if(rand() % 2)
115 | orcDYN->d_un.d_ptr = getElf_Addr();
116 | else
117 | return 0;
118 |
119 | fprintf(logfp, "(DYN[%d]->d_un.d_val = 0x"HEX")", entry, orcDYN->d_un.d_val);
120 |
121 | return 1;
122 | }
123 |
124 | int dyn5(void)
125 | {
126 | if(orcDYN->d_tag != DT_HASH &&
127 | orcDYN->d_tag != DT_GNU_HASH &&
128 | orcDYN->d_tag != DT_SYMTAB)
129 | return 0;
130 |
131 | if(rand() % 2)
132 | orcDYN->d_un.d_ptr = getElf_Addr();
133 |
134 | fprintf(logfp, "(DYN[%d]->d_un.d_val = 0x"HEX")", entry, orcDYN->d_un.d_val);
135 |
136 | return 1;
137 | }
138 |
139 | int dyn6(void)
140 | {
141 | if(orcDYN->d_tag != DT_INIT &&
142 | orcDYN->d_tag != DT_FINI)
143 | return 0;
144 |
145 | int r = rand();
146 |
147 | if(r % 3 == 0)
148 | orcDYN->d_un.d_ptr = getElf_Addr();
149 | else if(r % 3 == 1)
150 | orcDYN->d_un.d_ptr = orcHDR->e_entry; // jmp to the original entrypoint
151 | else {
152 | if(orcDYN->d_tag == DT_INIT)
153 | orcDYN->d_un.d_ptr = get_d_ptr_by_d_tag(DT_FINI);
154 | else
155 | orcDYN->d_un.d_ptr = get_d_ptr_by_d_tag(DT_INIT);
156 | }
157 |
158 | fprintf(logfp, "(DYN[%d]->d_un.d_val = 0x"HEX")", entry, orcDYN->d_un.d_val);
159 |
160 | return 1;
161 | }
162 |
163 | int dyn7(void)
164 | {
165 | if(orcDYN->d_tag != DT_DEBUG)
166 | return 0;
167 |
168 | if(rand() % 2)
169 | return 0;
170 |
171 | if(rand() % 2)
172 | orcDYN->d_tag = DT_SYMBOLIC;
173 | else
174 | orcDYN->d_tag = DT_TEXTREL;
175 |
176 | fprintf(logfp, "(DYN[%d]->d_tag = 0x"HEX")", entry, orcDYN->d_tag);
177 |
178 | return 1;
179 | }
180 |
181 | int dyn8(void)
182 | {
183 | if(orcDYN->d_tag != DT_PLTREL)
184 | return 0;
185 |
186 | if(rand() % 2)
187 | return 0;
188 |
189 | #if defined(__i386__) || defined(__ANDROID_API__)
190 | Elf_Word d_val;
191 | #elif defined(__x86_64__)
192 | Elf_Xword d_val;
193 | #endif
194 |
195 | while((d_val = rand() % DT_NUM))
196 | if(d_val != DT_REL && d_val != DT_RELA)
197 | break;
198 |
199 | orcDYN->d_un.d_val = d_val;
200 |
201 | fprintf(logfp, "(DYN[%d]->d_un.d_val = 0x"HEX")", entry, orcDYN->d_un.d_val);
202 |
203 | return 1;
204 | }
205 |
206 | int dyn9(void)
207 | {
208 | if(orcDYN->d_tag != DT_DEBUG)
209 | return 0;
210 |
211 | if(rand() % 2)
212 | return 0;
213 |
214 | orcDYN->d_tag = DT_BIND_NOW;
215 |
216 | fprintf(logfp, "(DYN[%d]->d_tag = 0x"HEX")", entry, orcDYN->d_tag);
217 |
218 | return 1;
219 | }
220 |
221 | int dyn10(void)
222 | {
223 | if(orcDYN->d_tag != DT_RPATH &&
224 | orcDYN->d_tag != DT_RUNPATH)
225 | return 0;
226 |
227 | unsigned int s = strlen(orcptr + linkstrtab_offset + elfDYN->d_un.d_val);
228 | char *rpath = malloc(s);
229 | char *fuzzed_path;
230 | int fuzzed = 0;
231 |
232 | *rpath = '\0';
233 | while(strlen(rpath) < s){
234 | fuzzed_path = get_fuzzed_path();
235 |
236 | if(strlen(rpath) + strlen(fuzzed_path) < s){
237 | strcat(rpath, fuzzed_path);
238 | fuzzed = 1;
239 | } else
240 | break;
241 |
242 | if(strlen(rpath) + 1 < s)
243 | strcat(rpath, ":");
244 |
245 | if(strlen(rpath) == s - 1)
246 | break;
247 | }
248 |
249 | if(!fuzzed)
250 | return 0;
251 |
252 | strncpy(orcptr + linkstrtab_offset + elfDYN->d_un.d_val, rpath, s);
253 |
254 | fprintf(logfp, "(DYN[%d]->(d_val + 0) = %s)", entry, orcptr + linkstrtab_offset + elfDYN->d_un.d_val);
255 |
256 | free(rpath);
257 |
258 | return 1;
259 | }
260 |
261 | int dyn11(void)
262 | {
263 | if(orcDYN->d_tag != DT_PLTREL)
264 | return 0;
265 |
266 | if(rand() % 2)
267 | return 0;
268 |
269 | #if defined(__i386__) || defined(__ANDROID_API__)
270 | orcDYN->d_un.d_val = DT_RELA;
271 | #elif defined(__x86_64__)
272 | orcDYN->d_un.d_val = DT_REL;
273 | #endif
274 |
275 | fprintf(logfp, "(DYN[%d]->d_un.d_val = 0x"HEX")", entry, orcDYN->d_un.d_val);
276 |
277 | return 1;
278 | }
279 |
280 | int dyn12(void)
281 | {
282 | if(orcDYN->d_tag != DT_PLTGOT)
283 | return 0;
284 |
285 | Elf_Section ndx;
286 |
287 | if(!(ndx = findSectionIndexByName(".got.plt")))
288 | return 0;
289 |
290 | Elf_Addr *d_ptr = (void *) orcptr + elfSHT[ndx].sh_offset;
291 |
292 | if(rand() % 5 == 0) // 20% chance to modify the first entry, which is the address of _DYNAMIC[]
293 | *d_ptr++ = getElf_Addr();
294 | else
295 | d_ptr++;
296 |
297 | *d_ptr++ = getElf_Addr();
298 | *d_ptr++ = getElf_Addr();
299 |
300 | d_ptr = (void *) orcptr + elfSHT[ndx].sh_offset; // Points back again to print the results
301 |
302 | fprintf(logfp, "(DYN[%d]->(d_un.d_ptr + 0) = 0x"HEX",", entry, *d_ptr++);
303 | fprintf(logfp, " (d_un.d_ptr + %d) = 0x"HEX",", (unsigned int) sizeof(Elf_Addr *), *d_ptr++);
304 | fprintf(logfp, " (d_un.d_ptr + %d) = 0x"HEX")", (unsigned int) sizeof(Elf_Addr *), *d_ptr);
305 |
306 | return 1;
307 | }
308 |
309 | int dyn13(void)
310 | {
311 | if(orcDYN->d_tag != DT_PLTRELSZ)
312 | return 0;
313 |
314 | if(rand() % 3 < 2)
315 | return 0;
316 |
317 | #if defined(__i386__) || defined(__ANDROID_API__)
318 | Elf_Sword d_tag;
319 | #elif defined(__x86_64__)
320 | Elf_Sxword d_tag;
321 | #endif
322 |
323 | if(rand() % 3 < 2){
324 | while((d_tag = rand() % 0xff))
325 | if(d_tag != DT_PLTRELSZ)
326 | break;
327 | } else
328 | #if defined(__i386__) || defined(__ANDROID_API__)
329 | d_tag = getElf_Word();
330 | #elif defined(__x86_64__)
331 | d_tag = getElf_Xword();
332 | #endif
333 |
334 | orcDYN->d_tag = d_tag;
335 |
336 | fprintf(logfp, "(DYN[%d]->d_tag = 0x"HEX")", entry, orcDYN->d_tag);
337 |
338 | return 1;
339 | }
340 |
341 | int dyn14(void)
342 | {
343 | if(orcDYN->d_tag != DT_RELASZ &&
344 | orcDYN->d_tag != DT_RELSZ &&
345 | orcDYN->d_tag != DT_RELAENT &&
346 | orcDYN->d_tag != DT_RELENT)
347 | return 0;
348 |
349 | if(rand() % 4 < 3)
350 | return 0;
351 |
352 | #if defined(__i386__) || defined(__ANDROID_API__)
353 | Elf_Sword d_tag;
354 | #elif defined(__x86_64__)
355 | Elf_Sxword d_tag;
356 | #endif
357 |
358 | if(rand() % 3 < 2){
359 | while((d_tag = rand() % 0xff))
360 | if(d_tag != DT_RELASZ &&
361 | d_tag != DT_RELSZ &&
362 | d_tag != DT_RELAENT &&
363 | d_tag != DT_RELENT)
364 | break;
365 | } else
366 | #if defined(__i386__) || defined(__ANDROID_API__)
367 | d_tag = getElf_Word();
368 | #elif defined(__x86_64__)
369 | d_tag = getElf_Xword();
370 | #endif
371 |
372 | orcDYN->d_tag = d_tag;
373 |
374 | fprintf(logfp, "(DYN[%d]->d_tag = 0x"HEX")", entry, orcDYN->d_tag);
375 |
376 | return 1;
377 | }
378 |
379 | int dyn15(void)
380 | {
381 | if(orcDYN->d_tag != DT_NULL)
382 | return 0;
383 |
384 | if(rand() % 5 < 3) // DT_NULL is fucking critical: is the end of _DYNAMIC[]
385 | return 0;
386 |
387 | #if defined(__i386__) || defined(__ANDROID_API__)
388 | Elf_Sword d_tag;
389 | #elif defined(__x86_64__)
390 | Elf_Sxword d_tag;
391 | #endif
392 |
393 | if(rand() % 3 < 2){
394 | while((d_tag = rand() % 0xff))
395 | if(d_tag != DT_NULL)
396 | break;
397 | } else
398 | #if defined(__i386__) || defined(__ANDROID_API__)
399 | d_tag = getElf_Word();
400 | #elif defined(__x86_64__)
401 | d_tag = getElf_Xword();
402 | #endif
403 |
404 | orcDYN->d_tag = d_tag;
405 |
406 | fprintf(logfp, "(DYN[%d]->d_tag = 0x"HEX")", entry, orcDYN->d_tag);
407 |
408 | return 1;
409 | }
410 |
411 | int dyn16(void)
412 | {
413 | if(orcDYN->d_tag != DT_INIT_ARRAY &&
414 | orcDYN->d_tag != DT_FINI_ARRAY)
415 | return 0;
416 |
417 | if(rand() % 2) // Constructors & Destructors are cool
418 | return 0;
419 |
420 | Elf_Word array_size;
421 | Elf_Section ndx;
422 |
423 | if(orcDYN->d_tag == DT_INIT_ARRAY)
424 | array_size = get_d_val_by_d_tag(DT_INIT_ARRAYSZ);
425 | else
426 | array_size = get_d_val_by_d_tag(DT_FINI_ARRAYSZ);
427 |
428 | if(array_size <= sizeof(Elf_Addr *)) // There's more than the default functions
429 | return 0;
430 |
431 | if(orcDYN->d_tag == DT_INIT_ARRAY){
432 | if(!(ndx = findSectionIndexByName(".init_array")))
433 | return 0;
434 | } else {
435 | if(!(ndx = findSectionIndexByName(".fini_array")))
436 | return 0;
437 | }
438 |
439 | Elf_Addr *d_ptr = (void *) orcptr + elfSHT[ndx].sh_offset;
440 |
441 | d_ptr++;
442 |
443 | *d_ptr = getElf_Addr(); // DT_(INIT|FINI)_ARRAY[1]
444 |
445 | d_ptr = (void *) orcptr + elfSHT[ndx].sh_offset; // Points back again to print the results
446 |
447 | fprintf(logfp, "(DYN[%d]->(d_un.d_ptr + 0) = 0x"HEX",", entry, *d_ptr++);
448 | fprintf(logfp, " (d_un.d_ptr + %d) = 0x"HEX")", (unsigned int) sizeof(Elf_Addr *), *d_ptr);
449 |
450 | return 1;
451 | }
452 |
453 | int dyn17(void)
454 | {
455 | if(orcDYN->d_tag != DT_INIT_ARRAYSZ &&
456 | orcDYN->d_tag != DT_FINI_ARRAYSZ)
457 | return 0;
458 |
459 | if(rand() % 2)
460 | return 0;
461 |
462 | #if defined(__i386__) || defined(__ANDROID_API__)
463 | Elf_Word d_val;
464 | #elif defined(__x86_64__)
465 | Elf_Xword d_val;
466 | #endif
467 |
468 | if(rand() % 2){
469 | while((d_val = rand() & 0xffff))
470 | if(d_val % 4 != 0)
471 | break;
472 | } else {
473 | d_val = orcDYN->d_un.d_val;
474 |
475 | #if defined(__i386__) || defined(__ANDROID_API__)
476 | d_val += 8; // A ptr in 64-bit is 8 bytes. Add 8 to 32-bit ELF
477 | #elif defined(__x86_64__)
478 | d_val += 4; // Vice versa
479 | #endif
480 | }
481 |
482 | orcDYN->d_un.d_val = d_val;
483 |
484 | fprintf(logfp, "(DYN[%d]->d_un.d_val = 0x"HEX")", entry, orcDYN->d_un.d_val);
485 |
486 | return 1;
487 | }
488 |
489 | int dyn18(void)
490 | {
491 | if(rand() % 20 < 19) // d_tag is critical
492 | return 0;
493 |
494 | // d_tag is a Sword (Signed Word)
495 | if(rand() % 2){ // 50% chance to set d_tag to a negative number > 0x7fffffff
496 | #if defined(__x86_64__)
497 | if(rand() % 2)
498 | orcDYN->d_tag = 0x8000000000000000 + (rand() % 0x7fffffff);
499 | else
500 | #endif
501 | orcDYN->d_tag = 0x80000000 + (rand() % 0x7fffffff);
502 | } else {
503 | if(rand() % 3 < 2){
504 | if(rand() % 2)
505 | orcDYN->d_tag = getElf_Word();
506 | else
507 | orcDYN->d_tag = getElf_Xword();
508 | } else {
509 | int r = rand();
510 |
511 | if(r % 4 == 0)
512 | orcDYN->d_tag = DT_LOOS;
513 | else if(r % 4 == 1)
514 | orcDYN->d_tag = DT_HIOS;
515 | else if(r % 4 == 2)
516 | orcDYN->d_tag = DT_LOPROC;
517 | else
518 | orcDYN->d_tag = DT_HIPROC;
519 | }
520 | }
521 |
522 | fprintf(logfp, "(DYN[%d]->d_tag = 0x"HEX")", entry, orcDYN->d_tag);
523 |
524 | return 1;
525 | }
526 |
527 |
528 | Elf_Addr get_d_ptr_by_d_tag(Elf_Sword d_tag)
529 | {
530 | int k;
531 | Elf_Dyn *tmpDYN = elfOrigDYN;
532 |
533 | for(k = 0; k < orcSHT->sh_size / orcSHT->sh_entsize; k++, tmpDYN++)
534 | if(tmpDYN->d_tag == d_tag)
535 | return tmpDYN->d_un.d_ptr;
536 |
537 | return (Elf_Addr) NULL;
538 | }
539 |
540 | Elf_Word get_d_val_by_d_tag(Elf_Sword d_tag)
541 | {
542 | int k;
543 | Elf_Dyn *tmpDYN = elfOrigDYN;
544 |
545 | for(k = 0; k < orcSHT->sh_size / orcSHT->sh_entsize; k++, tmpDYN++)
546 | if(tmpDYN->d_tag == d_tag)
547 | return tmpDYN->d_un.d_val;
548 |
549 | return 0;
550 | }
551 |
552 | void initialize_dyn_funcs(void)
553 | {
554 | dyn[1] = &dyn1;
555 | dyn[2] = &dyn2;
556 | dyn[3] = &dyn3;
557 | dyn[4] = &dyn4;
558 | dyn[5] = &dyn5;
559 | dyn[6] = &dyn6;
560 | dyn[7] = &dyn7;
561 | dyn[8] = &dyn8;
562 | dyn[9] = &dyn9;
563 | dyn[10] = &dyn10;
564 | dyn[11] = &dyn11;
565 | dyn[12] = &dyn12;
566 | dyn[13] = &dyn13;
567 | dyn[14] = &dyn14;
568 | dyn[15] = &dyn15;
569 | dyn[16] = &dyn16;
570 | dyn[17] = &dyn17;
571 | dyn[18] = &dyn18;
572 | }
573 |
--------------------------------------------------------------------------------
/jni/src/fuzz_hdr.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Melkor - An ELF File Format Fuzzer
3 | * Copyright (C) 2014 Alejandro Hernandez H. (nitr0us)
4 | *
5 | * Mexico
6 | */
7 |
8 | #include "melkor.h"
9 |
10 | #define N_RULES_HDR 19 // Total of fuzzing rules defined for this metadata type
11 |
12 | // Array of function pointers. Index zero won't be used. The fuzzing rules start from index 1
13 | func_ptr hdr[N_RULES_HDR + 1];
14 |
15 | void initialize_hdr_funcs(void) __attribute__((constructor));
16 |
17 | /* External vars */
18 | extern FILE *logfp;
19 | extern unsigned int mode; // Metadata to fuzz (parameters given in argv[])
20 | extern unsigned int quiet;
21 | extern unsigned int like_a, like_b;
22 | extern Elf_Ehdr *elfHDR, *orcHDR;
23 |
24 | void fuzz_hdr()
25 | {
26 | int rule;
27 |
28 | for(rule = 1; rule <= N_RULES_HDR; rule++)
29 | if((rand() % like_a) < like_b)
30 | if(hdr[rule]()){
31 | printf(". ");
32 | debug("HDR rule [%.2d] executed\n", rule);
33 | fprintf(logfp, " | HDR rule [%.2d] executed\n", rule);
34 | }
35 | }
36 |
37 | int hdr1(void)
38 | {
39 | if(mode & PHT)
40 | return 0;
41 |
42 | if(rand() % 2){ // 50% chance
43 | orcHDR->e_phoff = 0;
44 | orcHDR->e_phentsize = 0;
45 | fprintf(logfp, "(HDR->e_phoff = 0x00, e_phentsize = 0x00)");
46 | } else {
47 | orcHDR->e_phnum = 0;
48 | fprintf(logfp, "(HDR->e_phnum = 0x00)");
49 | }
50 |
51 | return 1;
52 | }
53 |
54 | int hdr2(void)
55 | {
56 | if(mode & SHT)
57 | return 0;
58 |
59 | if(rand() % 2){ // 50% chance
60 | orcHDR->e_shoff = 0;
61 | orcHDR->e_shentsize = 0;
62 | fprintf(logfp, "(HDR->e_shoff = 0x00, e_shentsize = 0x00)");
63 | } else {
64 | orcHDR->e_shnum = 0;
65 | fprintf(logfp, "(HDR->e_shnum = 0x00)");
66 | }
67 |
68 | return 1;
69 | }
70 |
71 | int hdr3(void)
72 | {
73 | Elf_Half e_type;
74 |
75 | if(rand() % 2) // 50% chance
76 | e_type = getElf_Half() % ET_NUM;
77 | else {
78 | if((rand() % 4) < 3){ // .5 * .75 = 37.5% chance
79 | while((e_type = (getElf_Half() % ET_HIPROC)))
80 | if(e_type >= 5 && e_type <= ET_HIPROC)
81 | break;
82 | } else // .5 * .25 = 12.5% chance
83 | e_type = 0;
84 | }
85 |
86 | orcHDR->e_type = e_type;
87 |
88 | fprintf(logfp, "(HDR->e_type = 0x%x)", orcHDR->e_type);
89 |
90 | return 1;
91 | }
92 |
93 | int hdr4(void)
94 | {
95 | if((rand() % 4) < 3){ // 75% chance
96 | while((orcHDR->e_machine = getElf_Half()))
97 | if(orcHDR->e_machine > 16)
98 | break;
99 | } else
100 | orcHDR->e_machine = 0;
101 |
102 | fprintf(logfp, "(HDR->e_machine = 0x%x)", orcHDR->e_machine);
103 |
104 | return 1;
105 | }
106 |
107 | int hdr5(void)
108 | {
109 | if((rand() % 4) < 3) // 75% chance
110 | orcHDR->e_entry = getElf_Addr();
111 | else
112 | orcHDR->e_entry = 0;
113 |
114 | fprintf(logfp, "(HDR->e_entry = 0x"HEX")", orcHDR->e_entry);
115 |
116 | return 1;
117 | }
118 |
119 | int hdr6(void)
120 | {
121 | if(mode & PHT)
122 | return 0;
123 |
124 | orcHDR->e_phoff = getElf_Off();
125 | fprintf(logfp, "(HDR->e_phoff = 0x"HEX")", orcHDR->e_phoff);
126 |
127 | return 1;
128 | }
129 |
130 | int hdr7(void)
131 | {
132 | orcHDR->e_ehsize = getElf_Half();
133 | fprintf(logfp, "(HDR->e_ehsize = 0x%x)", orcHDR->e_ehsize);
134 |
135 | return 1;
136 | }
137 |
138 | int hdr8(void)
139 | {
140 | if(mode & PHT)
141 | return 0;
142 |
143 | if((rand() % 4) < 3){ // 75% chance
144 | orcHDR->e_phentsize = getElf_Half();
145 | orcHDR->e_phnum = getElf_Half();
146 | fprintf(logfp, "(HDR->e_phentsize = 0x%x,", orcHDR->e_phentsize);
147 | fprintf(logfp, " e_phnum = 0x%x)", orcHDR->e_phnum);
148 | } else {
149 | orcHDR->e_phentsize = 0;
150 | fprintf(logfp, "(HDR->e_phentsize = 0x00)");
151 | }
152 |
153 | return 1;
154 | }
155 |
156 | int hdr9(void)
157 | {
158 | if((rand() % 4) < 3){ // 75% chance
159 | if(mode & SHT)
160 | return 0;
161 |
162 | orcHDR->e_shentsize = getElf_Half();
163 | orcHDR->e_shnum = getElf_Half();
164 | fprintf(logfp, "(HDR->e_shentsize = 0x%x,", orcHDR->e_shentsize);
165 | fprintf(logfp, " e_shnum = 0x%x)", orcHDR->e_shnum);
166 | } else {
167 | orcHDR->e_shentsize = 0;
168 | fprintf(logfp, "(HDR->e_shentsize = 0x00)");
169 | }
170 |
171 | return 1;
172 | }
173 |
174 | int hdr10(void)
175 | {
176 | if(mode & (STRS | NOTE | DYN | SYM | REL))
177 | return 0;
178 |
179 | if(mode & SHT)
180 | if(rand() % 3 < 2)
181 | return 0;
182 |
183 | if((rand() % 4) < 3) // 75% chance
184 | orcHDR->e_shstrndx = rand() % elfHDR->e_shnum;
185 | else {
186 | if(rand() % 2)
187 | orcHDR->e_shstrndx = getElf_Half();
188 | else
189 | orcHDR->e_shstrndx = 0;
190 | }
191 |
192 | fprintf(logfp, "(HDR->e_shstrndx = 0x%x)", orcHDR->e_shstrndx);
193 |
194 | return 1;
195 | }
196 |
197 | int hdr11(void)
198 | {
199 | if((rand() % 4) < 3) // 75% chance
200 | orcHDR->e_ident[EI_CLASS] = (rand() & 0xff) + ELFCLASS64 + 1;
201 | else
202 | orcHDR->e_ident[EI_CLASS] = 0;
203 |
204 | fprintf(logfp, "(HDR->e_ident[EI_CLASS] = 0x%.2x)", orcHDR->e_ident[EI_CLASS]);
205 |
206 | return 1;
207 | }
208 |
209 | int hdr12(void)
210 | {
211 | if((rand() % 4) < 3) // 75% chance
212 | orcHDR->e_ident[EI_DATA] = (rand() & 0xff) + ELFDATA2MSB + 1;
213 | else
214 | orcHDR->e_ident[EI_DATA] = 0;
215 |
216 | fprintf(logfp, "(HDR->e_ident[EI_DATA] = 0x%.2x)", orcHDR->e_ident[EI_DATA]);
217 |
218 | return 1;
219 | }
220 |
221 | int hdr13(void)
222 | {
223 | if(rand() % 2){
224 | orcHDR->e_version = getElf_Word() + EV_CURRENT + 1;
225 | orcHDR->e_ident[EI_VERSION] = (rand() & 0xff) + EV_CURRENT + 1;
226 | } else {
227 | orcHDR->e_version = 0;
228 | orcHDR->e_ident[EI_VERSION] = 0;
229 | }
230 |
231 | fprintf(logfp, "(HDR->e_version = 0x%x, e_ident[EI_VERSION] = 0x%.2x)", orcHDR->e_version, orcHDR->e_ident[EI_VERSION]);
232 |
233 | return 1;
234 | }
235 |
236 | int hdr14(void)
237 | {
238 | if(mode & SHT)
239 | return 0;
240 |
241 | orcHDR->e_shoff = getElf_Off();
242 | orcHDR->e_shnum = getElf_Half();
243 | orcHDR->e_shentsize = getElf_Half();
244 |
245 | fprintf(logfp, "(HDR->e_shoff = 0x"HEX",", orcHDR->e_shoff);
246 | fprintf(logfp, " e_shnum = 0x%x,", orcHDR->e_shnum);
247 | fprintf(logfp, " e_shentsize = 0x%x)", orcHDR->e_shentsize);
248 |
249 | return 1;
250 | }
251 |
252 | int hdr15(void)
253 | {
254 | if(mode & SHT)
255 | return 0;
256 |
257 | orcHDR->e_shnum = SHN_LORESERVE;
258 | fprintf(logfp, "(HDR->e_shnum = 0x%x)", orcHDR->e_shnum);
259 |
260 | return 1;
261 | }
262 |
263 | int hdr16(void)
264 | {
265 | orcHDR->e_ident[EI_ABIVERSION] = rand() & 0xff;
266 |
267 | fprintf(logfp, "(HDR->e_ident[EI_ABIVERSION] = 0x%.2x)", orcHDR->e_ident[EI_ABIVERSION]);
268 |
269 | return 1;
270 | }
271 |
272 | int hdr17(void)
273 | {
274 | orcHDR->e_ident[EI_OSABI] = rand() & 0xff;
275 |
276 | fprintf(logfp, "(HDR->e_ident[EI_OSABI] = 0x%.2x)", orcHDR->e_ident[EI_OSABI]);
277 |
278 | return 1;
279 | }
280 |
281 | int hdr18(void)
282 | {
283 | if(rand() % 2)
284 | orcHDR->e_type = ET_LOOS + 1;
285 | else
286 | orcHDR->e_type = ET_HIOS;
287 |
288 | fprintf(logfp, "(HDR->e_type = 0x%x)", orcHDR->e_type);
289 |
290 | return 1;
291 | }
292 |
293 | int hdr19(void)
294 | {
295 | if(mode & PHT)
296 | return 0;
297 |
298 | orcHDR->e_phnum = 32;
299 |
300 | fprintf(logfp, "(HDR->e_phnum = 0x00)");
301 |
302 | return 1;
303 | }
304 |
305 | void initialize_hdr_funcs(void)
306 | {
307 | hdr[1] = &hdr1;
308 | hdr[2] = &hdr2;
309 | hdr[3] = &hdr3;
310 | hdr[4] = &hdr4;
311 | hdr[5] = &hdr5;
312 | hdr[6] = &hdr6;
313 | hdr[7] = &hdr7;
314 | hdr[8] = &hdr8;
315 | hdr[9] = &hdr9;
316 | hdr[10] = &hdr10;
317 | hdr[11] = &hdr11;
318 | hdr[12] = &hdr12;
319 | hdr[13] = &hdr13;
320 | hdr[14] = &hdr14;
321 | hdr[15] = &hdr15;
322 | hdr[16] = &hdr16;
323 | hdr[17] = &hdr17;
324 | hdr[18] = &hdr18;
325 | hdr[19] = &hdr19;
326 | }
327 |
--------------------------------------------------------------------------------
/jni/src/fuzz_note.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Melkor - An ELF File Format Fuzzer
3 | * Copyright (C) 2014 Alejandro Hernandez H. (nitr0us)
4 | *
5 | * Mexico
6 | */
7 |
8 | #include "melkor.h"
9 |
10 | #define N_RULES_NOTE 4 // Total of fuzzing rules defined for this metadata type
11 |
12 | // Array of function pointers. Index zero won't be used. The fuzzing rules start from index 1
13 | func_ptr note[N_RULES_NOTE + 1];
14 |
15 | void initialize_note_funcs(void) __attribute__((constructor));
16 |
17 | /* External vars */
18 | extern FILE *logfp;
19 | extern unsigned int quiet;
20 | extern unsigned int like_a, like_b;
21 | extern unsigned int secnum;
22 | extern unsigned int entry;
23 | extern Elf_Nhdr *elfNOTE, *orcNOTE;
24 |
25 | void fuzz_note()
26 | {
27 | int rule;
28 |
29 | for(rule = 1; rule <= N_RULES_NOTE; rule++)
30 | if((rand() % like_a) < like_b)
31 | if(note[rule]()){
32 | printf(". ");
33 | debug("SHT[%d] NOTE[%d] rule [%.2d] executed\n", secnum, entry, rule);
34 | fprintf(logfp, " | SHT[%d] NOTE[%d] rule [%.2d] executed\n", secnum, entry, rule);
35 | }
36 | }
37 |
38 | int note1(void)
39 | {
40 | orcNOTE->n_namesz = getElf_Word();
41 |
42 | fprintf(logfp, "(NOTE[%d]->n_namesz = 0x%x)", entry, orcNOTE->n_namesz);
43 |
44 | return 1;
45 | }
46 |
47 | int note2(void)
48 | {
49 | unsigned int ptr_offset = 0;
50 | char *fmt_ptr;
51 |
52 | fprintf(logfp, "(NOTE[%d] + %d (sizeof(Elf_Nhdr)) + ", entry, (int) sizeof(Elf_Nhdr));
53 |
54 | if(rand() % 3 == 0)
55 | while(ptr_offset < elfNOTE->n_namesz){ // Trusting in n_namesz from the original ELF. This field in the Orc might be already fuzzed
56 | fmt_ptr = get_fmt_str();
57 |
58 | memcpy((void *) orcNOTE + sizeof(Elf_Nhdr) + ptr_offset, fmt_ptr, strlen(fmt_ptr));
59 | fprintf(logfp, "%d =%s, ", ptr_offset, fmt_ptr);
60 |
61 | ptr_offset += 4;
62 | }
63 | else
64 | while(ptr_offset < elfNOTE->n_namesz){
65 | if(*((char *) orcNOTE + sizeof(Elf_Nhdr) + ptr_offset) != 0){
66 | ptr_offset++;
67 | continue;
68 | }
69 |
70 | *((char *) orcNOTE + sizeof(Elf_Nhdr) + ptr_offset) = (rand() & 0x7f) + 0x80; // > 7-bit ASCII chars
71 | fprintf(logfp, "%d = %c (0x%.2x), ", ptr_offset, *((char *) orcNOTE + sizeof(Elf_Nhdr) + ptr_offset), *((char *) orcNOTE + sizeof(Elf_Nhdr) + ptr_offset) & 0xff);
72 | ptr_offset++;
73 | }
74 |
75 | fprintf(logfp, ")");
76 |
77 | return 1;
78 | }
79 |
80 | int note3(void)
81 | {
82 | unsigned int cnt = 0;
83 | int *desc = (int *) ((void *) orcNOTE + sizeof(Elf_Nhdr) + elfNOTE->n_namesz);
84 |
85 | fprintf(logfp, "(NOTE[%d] + %d (sizeof(Elf_Nhdr)) + %d (elfNOTE->n_namesz) + ", entry, (int) sizeof(Elf_Nhdr), elfNOTE->n_namesz);
86 |
87 | while(cnt < elfNOTE->n_descsz){ // Trusting in n_descsz from the original ELF. This field in the Orc might be already fuzzed
88 | *desc = getElf_Word();
89 |
90 | fprintf(logfp, "%d = 0x%x, ", cnt, *desc);
91 |
92 | desc++;
93 | cnt += sizeof(Elf_Word);
94 | }
95 |
96 | fprintf(logfp, ")");
97 |
98 | orcNOTE->n_descsz = getElf_Word();
99 |
100 | fprintf(logfp, "(NOTE[%d]->n_descsz = 0x%x)", entry, orcNOTE->n_descsz);
101 |
102 | return 1;
103 | }
104 |
105 | int note4(void)
106 | {
107 | if(rand() % 4 < 3) // Metadata in previous rules is used based upon n_type
108 | return 0;
109 |
110 | orcNOTE->n_type = 0x80000000 + (rand() % 0x7fffffff);
111 |
112 | fprintf(logfp, "(NOTE[%d]->n_type = 0x%x)", entry, orcNOTE->n_type);
113 |
114 | return 1;
115 | }
116 |
117 | void initialize_note_funcs(void)
118 | {
119 | note[1] = ¬e1;
120 | note[2] = ¬e2;
121 | note[3] = ¬e3;
122 | note[4] = ¬e4;
123 | }
124 |
--------------------------------------------------------------------------------
/jni/src/fuzz_pht.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Melkor - An ELF File Format Fuzzer
3 | * Copyright (C) 2014 Alejandro Hernandez H. (nitr0us)
4 | *
5 | * Mexico
6 | */
7 |
8 | #include "melkor.h"
9 |
10 | #define N_RULES_PHT 22 // Total of fuzzing rules defined for this metadata type
11 |
12 | // Array of function pointers. Index zero won't be used. The fuzzing rules start from index 1
13 | func_ptr pht[N_RULES_PHT + 1];
14 | int ph = 0; // Program Header. Used inside the for() loop in fuzz_pht() and will be used in the rules
15 |
16 | void initialize_pht_funcs(void) __attribute__((constructor));
17 |
18 | /* External vars */
19 | extern FILE *logfp;
20 | extern unsigned int mode; // Metadata to fuzz (parameters given in argv[])
21 | extern unsigned int quiet;
22 | extern unsigned int like_a, like_b;
23 | extern char *dirname_orcfname;
24 | extern char *orcptr;
25 | extern Elf_Ehdr *elfHDR;
26 | extern Elf_Ehdr *orcHDR;
27 | extern Elf_Phdr *elfPHT;
28 | extern Elf_Phdr *orcPHT;
29 | extern Elf_Phdr *orcOrigPHT;
30 |
31 | void fuzz_pht()
32 | {
33 | int rule;
34 |
35 | for(ph = 0; ph < orcHDR->e_phnum; ph++, orcPHT++)
36 | for(rule = 1; rule <= 18; rule++) // Rules from 19 will be executed outside the for() loop
37 | if((rand() % like_a) < like_b)
38 | if(pht[rule]()){
39 | printf(". ");
40 | debug("PHT[%d] rule [%.2d] executed\n", ph, rule);
41 | fprintf(logfp, " | PHT[%d] rule [%.2d] executed\n", ph, rule);
42 | }
43 |
44 | for( ; rule <= N_RULES_PHT; rule++)
45 | if((rand() % like_a) < like_b)
46 | if(pht[rule]()){
47 | printf(". ");
48 | debug("PHT rule [%.2d] executed\n", rule);
49 | fprintf(logfp, " | PHT rule [%.2d] executed\n", rule);
50 | }
51 | }
52 |
53 | int pht1(void)
54 | {
55 | if(orcPHT->p_type == PT_INTERP)
56 | return 0;
57 |
58 | if(orcPHT->p_type == PT_DYNAMIC)
59 | if(mode & DYN)
60 | return 0;
61 |
62 | if(orcPHT->p_type == PT_NOTE)
63 | if(mode & NOTE)
64 | return 0;
65 |
66 | if(rand() % 2) // p_type is a critical field
67 | return 0;
68 |
69 | Elf_Word p_type;
70 |
71 | if(rand() % 2){ // 50% chance
72 | while((p_type = rand() % PT_NUM)){
73 | switch(p_type){
74 | case PT_INTERP:
75 | continue;
76 | break;
77 | case PT_DYNAMIC:
78 | if(mode & DYN)
79 | continue;
80 | break;
81 | case PT_NOTE:
82 | if(mode & NOTE)
83 | continue;
84 | break;
85 | }
86 |
87 | break;
88 | }
89 | } else {
90 | if(rand() % 2)
91 | p_type = getElf_Word() + PT_NUM;
92 | else
93 | p_type = 0;
94 | }
95 |
96 | orcPHT->p_type = p_type;
97 |
98 | fprintf(logfp, "(PHT[%d]->p_type = 0x%x)", ph, orcPHT->p_type);
99 |
100 | return 1;
101 | }
102 |
103 | int pht2(void)
104 | {
105 | if(orcPHT->p_type == PT_INTERP)
106 | if(rand() % 5 < 4) // 80% chance
107 | return 0;
108 |
109 | if(orcPHT->p_type == PT_DYNAMIC)
110 | if(mode & DYN)
111 | return 0;
112 |
113 | if(orcPHT->p_type == PT_NOTE)
114 | if(mode & NOTE)
115 | return 0;
116 |
117 | Elf_Off p_offset;
118 |
119 | if(rand() % 3 < 2){ // 66.66% chance
120 | while((p_offset = getElf_Off()))
121 | if(p_offset % PAGESIZE == 0)
122 | break;
123 | } else {
124 | while((p_offset = getElf_Off()))
125 | if(p_offset % PAGESIZE != 0)
126 | break;
127 | }
128 |
129 | orcPHT->p_offset = p_offset;
130 |
131 | fprintf(logfp, "(PHT[%d]->p_offset = 0x"HEX")", ph, orcPHT->p_offset);
132 |
133 | return 1;
134 | }
135 |
136 | int pht3(void)
137 | {
138 | if(orcPHT->p_type == PT_INTERP)
139 | if(rand() % 5 < 4) // 80% chance
140 | return 0;
141 |
142 | if(orcPHT->p_type == PT_DYNAMIC)
143 | if(mode & DYN)
144 | return 0;
145 |
146 | if(orcPHT->p_type == PT_NOTE)
147 | if(mode & NOTE)
148 | return 0;
149 |
150 | Elf_Addr v, p;
151 |
152 | if(rand() % 2){
153 | if(rand() % 3 < 2){ // .5 * .6666 = 33.33% chance
154 | v = orcPHT->p_vaddr;
155 | p = getElf_Addr();
156 | } else { // 16.66% chance
157 | v = getElf_Addr();
158 | p = orcPHT->p_paddr;
159 | }
160 | } else {
161 | if(rand() % 2){ // .5 * .5 = 25% chance
162 | while((v = getElf_Addr()))
163 | if(v % PAGESIZE == 0){
164 | if(rand() % 2)
165 | p = v;
166 | else
167 | p = getElf_Addr();
168 | break;
169 | }
170 | } else { // 25% chance
171 | while((v = getElf_Addr()))
172 | if(v % PAGESIZE != 0){
173 | if(rand() % 2)
174 | p = v;
175 | else
176 | p = getElf_Addr();
177 | break;
178 | }
179 | }
180 | }
181 |
182 | orcPHT->p_vaddr = v;
183 | orcPHT->p_paddr = p;
184 |
185 | fprintf(logfp, "(PHT[%d]->p_vaddr = 0x"HEX",", ph, orcPHT->p_vaddr);
186 | fprintf(logfp, " p_paddr = 0x"HEX")", orcPHT->p_paddr);
187 |
188 | return 1;
189 | }
190 |
191 | int pht4(void)
192 | {
193 | if(orcPHT->p_type == PT_INTERP)
194 | if(rand() % 5 < 4) // 80% chance
195 | return 0;
196 |
197 | if(orcPHT->p_type == PT_DYNAMIC)
198 | if(mode & DYN)
199 | return 0;
200 |
201 | if(orcPHT->p_type == PT_NOTE)
202 | if(mode & NOTE)
203 | return 0;
204 |
205 | #if defined(__i386__) || defined(__ANDROID_API__)
206 | Elf_Word p_memsz;
207 | #elif defined(__x86_64__)
208 | Elf_Xword p_memsz;
209 | #endif
210 | int r = rand();
211 |
212 | if(r % 3 == 0){
213 | orcPHT->p_filesz = 0;
214 | #if defined(__i386__) || defined(__ANDROID_API__)
215 | while((p_memsz = getElf_Word()))
216 | #elif defined(__x86_64__)
217 | while((p_memsz = getElf_Xword()))
218 | #endif
219 | if(p_memsz % PAGESIZE == 0){
220 | orcPHT->p_memsz = p_memsz;
221 | break;
222 | }
223 | } else if(r % 3 == 1){
224 | #if defined(__i386__) || defined(__ANDROID_API__)
225 | orcPHT->p_filesz = getElf_Word();
226 | #elif defined(__x86_64__)
227 | orcPHT->p_filesz = getElf_Xword();
228 | #endif
229 | orcPHT->p_memsz = 0;
230 | } else {
231 | if(rand() % 2){
232 | orcPHT->p_filesz = 0;
233 | orcPHT->p_memsz = 0;
234 | } else
235 | orcPHT->p_memsz = getElf_Word();
236 | }
237 |
238 | fprintf(logfp, "(PHT[%d]->p_filesz = 0x"HEX",", ph, orcPHT->p_filesz);
239 | fprintf(logfp, " p_memsz = 0x"HEX")", orcPHT->p_memsz);
240 |
241 | return 1;
242 | }
243 |
244 | int pht5(void)
245 | {
246 | if(rand() % 2){
247 | if(rand() % 2)
248 | orcPHT->p_align = PAGESIZE - 1;
249 | else
250 | orcPHT->p_align = PAGESIZE + 1;
251 | } else
252 | #if defined(__i386__) || defined(__ANDROID_API__)
253 | orcPHT->p_align = getElf_Word();
254 | #elif defined(__x86_64__)
255 | orcPHT->p_align = getElf_Xword();
256 | #endif
257 |
258 | fprintf(logfp, "(PHT[%d]->p_align = 0x"HEX")", ph, orcPHT->p_align);
259 |
260 | return 1;
261 | }
262 |
263 | int pht6(void)
264 | {
265 | if(orcPHT->p_type == PT_INTERP)
266 | return 0;
267 |
268 | if(orcPHT->p_type == PT_DYNAMIC)
269 | if(mode & DYN)
270 | return 0;
271 |
272 | if(orcPHT->p_type == PT_NOTE)
273 | if(mode & NOTE)
274 | return 0;
275 |
276 | if(rand() % 2) // p_type is a critical field
277 | return 0;
278 |
279 | Elf_Word p_type;
280 |
281 | while((p_type = (getElf_Word() + PT_LOPROC)))
282 | if(p_type >= PT_LOPROC && p_type < PT_HIPROC)
283 | break;
284 |
285 | orcPHT->p_type = p_type;
286 |
287 | fprintf(logfp, "(PHT[%d]->p_type = 0x%x)", ph, orcPHT->p_type);
288 |
289 | return 1;
290 | }
291 |
292 | int pht7(void)
293 | {
294 | if(orcPHT->p_type == PT_INTERP)
295 | if(rand() % 5 < 4) // 80% chance
296 | return 0;
297 |
298 | if(orcPHT->p_type == PT_DYNAMIC)
299 | if(mode & DYN)
300 | return 0;
301 |
302 | if(orcPHT->p_type == PT_NOTE)
303 | if(mode & NOTE)
304 | return 0;
305 |
306 | #if defined(__i386__) || defined(__ANDROID_API__)
307 | Elf_Word p_filesz;
308 | #elif defined(__x86_64__)
309 | Elf_Xword p_filesz;
310 | #endif
311 |
312 | if(rand() % 3 < 2){
313 | #if defined(__i386__) || defined(__ANDROID_API__)
314 | while((p_filesz = getElf_Word()))
315 | #elif defined(__x86_64__)
316 | while((p_filesz = getElf_Xword()))
317 | #endif
318 | if(p_filesz > orcPHT->p_memsz){
319 | orcPHT->p_filesz = p_filesz;
320 | break;
321 | }
322 | } else
323 | #if defined(__i386__) || defined(__ANDROID_API__)
324 | orcPHT->p_filesz = getElf_Word();
325 | #elif defined(__x86_64__)
326 | orcPHT->p_filesz = getElf_Xword();
327 | #endif
328 |
329 | fprintf(logfp, "(PHT[%d]->p_filesz = 0x"HEX")", ph, orcPHT->p_filesz);
330 |
331 | return 1;
332 | }
333 |
334 | int pht8(void)
335 | {
336 | if(orcPHT->p_type != PT_NOTE)
337 | return 0;
338 |
339 | if(mode & NOTE)
340 | return 0;
341 |
342 | #if defined(__i386__) || defined(__ANDROID_API__)
343 | Elf_Word p_filesz;
344 | #elif defined(__x86_64__)
345 | Elf_Xword p_filesz;
346 | #endif
347 |
348 | while((p_filesz = getElf_Half()))
349 | if(p_filesz % sizeof(Elf_Word) != 0)
350 | break;
351 |
352 | orcPHT->p_filesz = p_filesz;
353 |
354 | fprintf(logfp, "(PHT[%d]->p_filesz = 0x"HEX")", ph, orcPHT->p_filesz);
355 |
356 | return 1;
357 | }
358 |
359 | int pht9(void)
360 | {
361 | if(orcPHT->p_type != PT_INTERP)
362 | return 0;
363 |
364 | if(rand() % 3 == 0) // p_type is a critical field
365 | return 0;
366 |
367 | Elf_Word p_type;
368 | int r = rand();
369 |
370 | if(r % 4 == 0){ // 25% chance
371 | while((p_type = getElf_Word())){
372 | switch(p_type){
373 | case PT_INTERP:
374 | continue;
375 | break;
376 | case PT_DYNAMIC:
377 | if(mode & DYN)
378 | continue;
379 | break;
380 | case PT_NOTE:
381 | if(mode & NOTE)
382 | continue;
383 | break;
384 | }
385 |
386 | break;
387 | }
388 |
389 | orcPHT->p_type = p_type;
390 |
391 | fprintf(logfp, "(PHT[%d]->p_type = 0x%x)", ph, orcPHT->p_type);
392 | } else if(r % 4 == 1){ // 25% chance
393 | int k;
394 | Elf_Phdr *tmpPHT = elfPHT;
395 |
396 | for(k = 0; k < elfHDR->e_phnum; k++, tmpPHT++)
397 | if(tmpPHT->p_type == PT_INTERP){
398 | strncpy(orcptr + tmpPHT->p_offset, dirname_orcfname, strlen(dirname_orcfname));
399 | *(orcptr + tmpPHT->p_offset + strlen(dirname_orcfname)) = '\0';
400 |
401 | fprintf(logfp, "(PHT[PT_INTERP] = %s)", orcptr + tmpPHT->p_offset);
402 |
403 | return 1;
404 | }
405 |
406 | return 0; // Not found
407 | } else if(ph > 0){
408 | if(rand() % 2){
409 | if(mode & DYN)
410 | if(orcOrigPHT[ph - 1].p_type == PT_DYNAMIC)
411 | return 0;
412 |
413 | if(mode & NOTE)
414 | if(orcOrigPHT[ph - 1].p_type == PT_NOTE)
415 | return 0;
416 |
417 | orcOrigPHT[ph - 1].p_type = PT_INTERP;
418 |
419 | fprintf(logfp, "(PHT[%d - 1]->p_type = 0x%x)", ph, orcOrigPHT[ph - 1].p_type);
420 | } else if(ph < (orcHDR->e_phnum - 1)){
421 | if(mode & DYN)
422 | if(orcOrigPHT[ph + 1].p_type == PT_DYNAMIC)
423 | return 0;
424 |
425 | if(mode & NOTE)
426 | if(orcOrigPHT[ph + 1].p_type == PT_NOTE)
427 | return 0;
428 |
429 | orcOrigPHT[ph + 1].p_type = PT_INTERP;
430 |
431 | fprintf(logfp, "(PHT[%d + 1]->p_type = 0x%x)", ph, orcOrigPHT[ph + 1].p_type);
432 | }
433 | } else
434 | return 0;
435 |
436 | return 1;
437 | }
438 |
439 | int pht10(void)
440 | {
441 | if(rand() % 2)
442 | orcPHT->p_flags = getElf_Half();
443 | else
444 | orcPHT->p_flags |= PF_MASKPROC;
445 |
446 | fprintf(logfp, "(PHT[%d]->p_flags = 0x%x)", ph, orcPHT->p_flags);
447 |
448 | return 1;
449 | }
450 |
451 | int pht11(void)
452 | {
453 | if(orcPHT->p_flags & PF_X)
454 | orcPHT->p_flags |= PF_W;
455 | else
456 | return 0;
457 |
458 | fprintf(logfp, "(PHT[%d]->p_flags = 0x%x)", ph, orcPHT->p_flags);
459 |
460 | return 1;
461 | }
462 |
463 | int pht12(void)
464 | {
465 | if(orcPHT->p_type != PT_DYNAMIC)
466 | return 0;
467 |
468 | if(mode & DYN)
469 | return 0;
470 |
471 | orcPHT->p_offset = getElf_Off();
472 | orcPHT->p_vaddr = getElf_Addr();
473 |
474 | fprintf(logfp, "(PHT[%d]->p_offset = 0x"HEX",", ph, orcPHT->p_offset);
475 | fprintf(logfp, " p_vaddr = 0x"HEX")", orcPHT->p_vaddr);
476 |
477 | return 1;
478 | }
479 |
480 | int pht13(void)
481 | {
482 | if(rand() % 2) // p_type is a critical field
483 | return 0;
484 |
485 | if(orcOrigPHT[orcHDR->e_phnum - 1].p_type != PT_NULL &&
486 | orcOrigPHT[orcHDR->e_phnum - 1].p_type != PT_GNU_RELRO &&
487 | orcOrigPHT[orcHDR->e_phnum - 1].p_type != PT_GNU_EH_FRAME &&
488 | orcOrigPHT[orcHDR->e_phnum - 1].p_type != PT_GNU_STACK)
489 | return 0;
490 |
491 | orcOrigPHT[orcHDR->e_phnum - 1].p_type = PT_SHLIB;
492 |
493 | fprintf(logfp, "(PHT[%d - 1]->p_type = 0x%x)", orcHDR->e_phnum, orcOrigPHT[orcHDR->e_phnum - 1].p_type);
494 |
495 | return 1;
496 | }
497 |
498 | int pht14(void)
499 | {
500 | if(orcPHT->p_type != PT_NULL &&
501 | orcPHT->p_type != PT_GNU_RELRO &&
502 | orcPHT->p_type != PT_GNU_EH_FRAME &&
503 | orcPHT->p_type != PT_GNU_STACK)
504 | return 0;
505 |
506 | if(rand() % 2) // p_type is a critical field
507 | return 0;
508 |
509 | if(rand() % 2)
510 | orcPHT->p_type = PT_LOOS;
511 | else
512 | orcPHT->p_type = PT_HIOS;
513 |
514 | fprintf(logfp, "(PHT[%d]->p_type = 0x%x)", ph, orcPHT->p_type);
515 |
516 | return 1;
517 | }
518 |
519 | int pht15(void)
520 | {
521 | orcPHT->p_flags |= PF_MASKOS;
522 |
523 | fprintf(logfp, "(PHT[%d]->p_flags = 0x%x)", ph, orcPHT->p_flags);
524 |
525 | return 1;
526 | }
527 |
528 | int pht16(void)
529 | {
530 | if(orcPHT->p_type != PT_PAX_FLAGS &&
531 | orcPHT->p_type != PT_GNU_RELRO &&
532 | orcPHT->p_type != PT_GNU_STACK)
533 | return 0;
534 |
535 | if(rand() % 3 == 0)
536 | orcPHT->p_offset = getElf_Off();
537 | orcPHT->p_vaddr = getElf_Addr();
538 | #if defined(__i386__) || defined(__ANDROID_API__)
539 | orcPHT->p_filesz = getElf_Word();
540 | #elif defined(__x86_64__)
541 | orcPHT->p_filesz = getElf_Xword();
542 | #endif
543 | #if defined(__i386__) || defined(__ANDROID_API__)
544 | orcPHT->p_memsz = getElf_Word();
545 | #elif defined(__x86_64__)
546 | orcPHT->p_memsz = getElf_Xword();
547 | #endif
548 | orcPHT->p_flags = getElf_Word();
549 | #if defined(__i386__) || defined(__ANDROID_API__)
550 | orcPHT->p_align = getElf_Word();
551 | #elif defined(__x86_64__)
552 | orcPHT->p_align = getElf_Xword();
553 | #endif
554 |
555 | fprintf(logfp, "(PHT[%d]->p_offset = 0x"HEX",", ph, orcPHT->p_offset);
556 | fprintf(logfp, " p_vaddr = 0x"HEX",", orcPHT->p_vaddr);
557 | fprintf(logfp, " p_filesz = 0x"HEX",", orcPHT->p_filesz);
558 | fprintf(logfp, " p_memsz = 0x"HEX",", orcPHT->p_memsz);
559 | fprintf(logfp, " p_flags = 0x%x,", orcPHT->p_flags);
560 | fprintf(logfp, " p_align = 0x"HEX")", orcPHT->p_align);
561 |
562 | return 1;
563 | }
564 |
565 | int pht17(void)
566 | {
567 | if(orcPHT->p_type != PT_TLS)
568 | return 0;
569 |
570 | if(rand() % 3 == 0)
571 | orcPHT->p_offset = getElf_Off();
572 | orcPHT->p_vaddr = getElf_Addr();
573 | #if defined(__i386__) || defined(__ANDROID_API__)
574 | orcPHT->p_filesz = getElf_Word();
575 | #elif defined(__x86_64__)
576 | orcPHT->p_filesz = getElf_Xword();
577 | #endif
578 | #if defined(__i386__) || defined(__ANDROID_API__)
579 | orcPHT->p_memsz = getElf_Word();
580 | #elif defined(__x86_64__)
581 | orcPHT->p_memsz = getElf_Xword();
582 | #endif
583 | orcPHT->p_flags = getElf_Word();
584 | #if defined(__i386__) || defined(__ANDROID_API__)
585 | orcPHT->p_align = getElf_Word();
586 | #elif defined(__x86_64__)
587 | orcPHT->p_align = getElf_Xword();
588 | #endif
589 |
590 | fprintf(logfp, "(PHT[%d]->p_offset = 0x"HEX",", ph, orcPHT->p_offset);
591 | fprintf(logfp, " p_vaddr = 0x"HEX",", orcPHT->p_vaddr);
592 | fprintf(logfp, " p_filesz = 0x"HEX",", orcPHT->p_filesz);
593 | fprintf(logfp, " p_memsz = 0x"HEX",", orcPHT->p_memsz);
594 | fprintf(logfp, " p_flags = 0x%x,", orcPHT->p_flags);
595 | fprintf(logfp, " p_align = 0x"HEX")", orcPHT->p_align);
596 |
597 | return 1;
598 | }
599 |
600 | int pht18(void)
601 | {
602 | if(orcPHT->p_type != PT_GNU_EH_FRAME)
603 | return 0;
604 |
605 | if(rand() % 3 == 0)
606 | orcPHT->p_offset = getElf_Off();
607 | orcPHT->p_vaddr = getElf_Addr();
608 | #if defined(__i386__) || defined(__ANDROID_API__)
609 | orcPHT->p_filesz = getElf_Word();
610 | #elif defined(__x86_64__)
611 | orcPHT->p_filesz = getElf_Xword();
612 | #endif
613 | #if defined(__i386__) || defined(__ANDROID_API__)
614 | orcPHT->p_memsz = getElf_Word();
615 | #elif defined(__x86_64__)
616 | orcPHT->p_memsz = getElf_Xword();
617 | #endif
618 | orcPHT->p_flags = getElf_Word();
619 | #if defined(__i386__) || defined(__ANDROID_API__)
620 | orcPHT->p_align = getElf_Word();
621 | #elif defined(__x86_64__)
622 | orcPHT->p_align = getElf_Xword();
623 | #endif
624 |
625 | fprintf(logfp, "(PHT[%d]->p_offset = 0x"HEX",", ph, orcPHT->p_offset);
626 | fprintf(logfp, " p_vaddr = 0x"HEX",", orcPHT->p_vaddr);
627 | fprintf(logfp, " p_filesz = 0x"HEX",", orcPHT->p_filesz);
628 | fprintf(logfp, " p_memsz = 0x"HEX",", orcPHT->p_memsz);
629 | fprintf(logfp, " p_flags = 0x%x,", orcPHT->p_flags);
630 | fprintf(logfp, " p_align = 0x"HEX")", orcPHT->p_align);
631 |
632 | return 1;
633 | }
634 |
635 | int pht19(void)
636 | {
637 | int p, last_PT = -1;
638 | Elf_Phdr *tmpPHT = orcOrigPHT;
639 | int r = rand();
640 |
641 | if(r % 3 == 0){ // 33.33% chance // Deletes the PT_PHDR from the PHT
642 | for(p = 0; p < orcHDR->e_phnum; p++, tmpPHT++)
643 | if(tmpPHT->p_type == PT_PHDR){
644 | tmpPHT->p_type = getElf_Word();
645 |
646 | fprintf(logfp, "(PHT[%d]->p_type = 0x%x)", p, tmpPHT->p_type);
647 |
648 | break;
649 | }
650 | } else if(r % 3 == 1){ // Create an extra PT_PHT right after the first one found in the PHT
651 | for(p = 0; p < orcHDR->e_phnum; p++, tmpPHT++)
652 | if(tmpPHT->p_type == PT_PHDR)
653 | last_PT = p;
654 |
655 | if(last_PT == -1)
656 | return 0;
657 |
658 | if(last_PT == (orcHDR->e_phnum - 1)){ // No more program headers
659 | if(mode & DYN)
660 | if(orcOrigPHT[last_PT].p_type == PT_DYNAMIC)
661 | return 0;
662 |
663 | if(mode & NOTE)
664 | if(orcOrigPHT[last_PT].p_type == PT_NOTE)
665 | return 0;
666 |
667 | orcOrigPHT[last_PT].p_type = PT_PHDR;
668 |
669 | fprintf(logfp, "(PHT[%d]->p_type = 0x%x)", last_PT, orcOrigPHT[last_PT].p_type);
670 | } else { // Set to PT_PHT right after the latest found
671 | if(mode & DYN)
672 | if(orcOrigPHT[last_PT + 1].p_type == PT_DYNAMIC)
673 | return 0;
674 |
675 | if(mode & NOTE)
676 | if(orcOrigPHT[last_PT + 1].p_type == PT_NOTE)
677 | return 0;
678 |
679 | orcOrigPHT[last_PT + 1].p_type = PT_PHDR;
680 |
681 | fprintf(logfp, "(PHT[%d + 1]->p_type = 0x%x)", last_PT, orcOrigPHT[last_PT + 1].p_type);
682 | }
683 | } else { // Set to PT_PHDR the latest entry in the PHT (after the PT_LOAD segments)
684 | if(mode & DYN)
685 | if(orcOrigPHT[orcHDR->e_phnum - 1].p_type == PT_DYNAMIC)
686 | return 0;
687 |
688 | if(mode & NOTE)
689 | if(orcOrigPHT[orcHDR->e_phnum - 1].p_type == PT_NOTE)
690 | return 0;
691 |
692 | orcOrigPHT[orcHDR->e_phnum - 1].p_type = PT_PHDR;
693 |
694 | fprintf(logfp, "(PHT[%d - 1]->p_type = 0x%x)", orcHDR->e_phnum, orcOrigPHT[orcHDR->e_phnum - 1].p_type);
695 | }
696 |
697 | return 1;
698 | }
699 |
700 | int pht20(void)
701 | {
702 | int a, b;
703 | Elf_Phdr swap;
704 |
705 | // Bubble sort algorithm to put the PT_LOAD segments in decreasing order based in their p_vaddr
706 | for(a = 0; a < orcHDR->e_phnum - 1; a++){
707 | if(orcOrigPHT[a].p_type != PT_LOAD)
708 | continue;
709 |
710 | for(b = 0; b < orcHDR->e_phnum - 1 - a; b++){
711 | if(orcOrigPHT[b].p_type != PT_LOAD)
712 | continue;
713 |
714 | if(orcOrigPHT[b].p_vaddr < orcOrigPHT[a].p_vaddr){
715 | memcpy(&swap, &orcOrigPHT[b], sizeof(Elf_Phdr));
716 | memcpy(&orcOrigPHT[b], &orcOrigPHT[b + 1], sizeof(Elf_Phdr));
717 | memcpy(&orcOrigPHT[b + 1], &swap, sizeof(Elf_Phdr));
718 | }
719 | }
720 | }
721 |
722 | fprintf(logfp, "(PHT[PT_LOAD].p_vaddr reordered [descending])");
723 |
724 | return 1;
725 | }
726 |
727 | int pht21(void)
728 | {
729 | int p, last_INTERP = -1;
730 | Elf_Phdr swap, *tmpPHT = orcOrigPHT;
731 |
732 | for(p = 0; p < orcHDR->e_phnum; p++, tmpPHT++)
733 | if(tmpPHT->p_type == PT_INTERP)
734 | last_INTERP = p;
735 |
736 | if(last_INTERP == -1)
737 | return 0;
738 |
739 | memcpy(&swap, &orcOrigPHT[last_INTERP], sizeof(Elf_Phdr));
740 | memcpy(&orcOrigPHT[last_INTERP], &orcOrigPHT[orcHDR->e_phnum - 1], sizeof(Elf_Phdr));
741 | memcpy(&orcOrigPHT[orcHDR->e_phnum - 1], &swap, sizeof(Elf_Phdr));
742 |
743 | fprintf(logfp, "(PHT[PT_INTERP] relocated to the end of the PHT. PHT[%d] is now PHT[%d])", orcHDR->e_phnum - 1, last_INTERP);
744 |
745 | return 1;
746 | }
747 |
748 | int pht22(void)
749 | {
750 | int p, found = 0;
751 | Elf_Phdr *tmpPHT = orcOrigPHT;
752 |
753 | for(p = 0; p < orcHDR->e_phnum; p++, tmpPHT++)
754 | if(tmpPHT->p_type == PT_DYNAMIC){
755 | found++;
756 | break;
757 | }
758 |
759 | if(found){
760 | if(mode & DYN)
761 | return 0;
762 |
763 | if(rand() % 2) // PT_DYNAMIC is important
764 | return 0;
765 |
766 | if(rand() % 3 == 0)
767 | tmpPHT->p_offset = getElf_Off();
768 | tmpPHT->p_vaddr = getElf_Addr();
769 | #if defined(__i386__) || defined(__ANDROID_API__)
770 | tmpPHT->p_filesz = getElf_Word();
771 | #elif defined(__x86_64__)
772 | tmpPHT->p_filesz = getElf_Xword();
773 | #endif
774 | #if defined(__i386__) || defined(__ANDROID_API__)
775 | tmpPHT->p_memsz = getElf_Word();
776 | #elif defined(__x86_64__)
777 | tmpPHT->p_memsz = getElf_Xword();
778 | #endif
779 | tmpPHT->p_flags = getElf_Word();
780 | #if defined(__i386__) || defined(__ANDROID_API__)
781 | tmpPHT->p_align = getElf_Word();
782 | #elif defined(__x86_64__)
783 | tmpPHT->p_align = getElf_Xword();
784 | #endif
785 |
786 | fprintf(logfp, "(PHT[%d]->p_offset = 0x"HEX",", p, tmpPHT->p_offset);
787 | fprintf(logfp, " p_vaddr = 0x"HEX",", tmpPHT->p_vaddr);
788 | fprintf(logfp, " p_filesz = 0x"HEX",", tmpPHT->p_filesz);
789 | fprintf(logfp, " p_memsz = 0x"HEX",", tmpPHT->p_memsz);
790 | fprintf(logfp, " p_flags = 0x%x,", tmpPHT->p_flags);
791 | fprintf(logfp, " p_align = 0x"HEX")", tmpPHT->p_align);
792 |
793 | return 1;
794 | } else {
795 | tmpPHT = orcOrigPHT;
796 |
797 | for(p = 0; p < orcHDR->e_phnum; p++, tmpPHT++)
798 | if(tmpPHT->p_type == PT_NULL){
799 | if(mode & DYN)
800 | return 0;
801 |
802 | tmpPHT->p_type = PT_DYNAMIC;
803 |
804 | fprintf(logfp, "(PHT[%d]->p_type = 0x%x)", p, tmpPHT->p_type);
805 |
806 | return 1;
807 | }
808 |
809 | tmpPHT = orcOrigPHT;
810 |
811 | // Less priority than overwriting a PT_NULL
812 | for(p = 0; p < orcHDR->e_phnum; p++, tmpPHT++)
813 | if(tmpPHT->p_type == PT_GNU_STACK){
814 | if(mode & DYN)
815 | return 0;
816 |
817 | tmpPHT->p_type = PT_DYNAMIC;
818 |
819 | fprintf(logfp, "(PHT[%d]->p_type = 0x%x)", p, tmpPHT->p_type);
820 |
821 | return 1;
822 | }
823 |
824 | return 0;
825 | }
826 | }
827 |
828 | void initialize_pht_funcs(void)
829 | {
830 | pht[1] = &pht1;
831 | pht[2] = &pht2;
832 | pht[3] = &pht3;
833 | pht[4] = &pht4;
834 | pht[5] = &pht5;
835 | pht[6] = &pht6;
836 | pht[7] = &pht7;
837 | pht[8] = &pht8;
838 | pht[9] = &pht9;
839 | pht[10] = &pht10;
840 | pht[11] = &pht11;
841 | pht[12] = &pht12;
842 | pht[13] = &pht13;
843 | pht[14] = &pht14;
844 | pht[15] = &pht15;
845 | pht[16] = &pht16;
846 | pht[17] = &pht17;
847 | pht[18] = &pht18;
848 | pht[19] = &pht19;
849 | pht[20] = &pht20;
850 | pht[21] = &pht21;
851 | pht[22] = &pht22;
852 | }
853 |
--------------------------------------------------------------------------------
/jni/src/fuzz_rel.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Melkor - An ELF File Format Fuzzer
3 | * Copyright (C) 2014 Alejandro Hernandez H. (nitr0us)
4 | *
5 | * Mexico
6 | */
7 |
8 | #include "melkor.h"
9 |
10 | #define N_RULES_REL 3 // Total of fuzzing rules defined for this metadata type
11 |
12 | // Array of function pointers. Index zero won't be used. The fuzzing rules start from index 1
13 | func_ptr rel[N_RULES_REL + 1];
14 |
15 | void initialize_rel_funcs(void) __attribute__((constructor));
16 |
17 | /* External vars */
18 | extern FILE *logfp;
19 | extern unsigned int quiet;
20 | extern unsigned int like_a, like_b;
21 | extern unsigned int secnum;
22 | extern unsigned int entry;
23 | extern Elf_Ehdr *orcHDR;
24 | extern Elf_Shdr *orcSHT;
25 | extern Elf_Rel *orcREL;
26 | extern Elf_Rela *orcRELA;
27 |
28 | void fuzz_rel()
29 | {
30 | int rule;
31 |
32 | for(rule = 1; rule <= N_RULES_REL; rule++)
33 | if((rand() % like_a) < like_b)
34 | if(rel[rule]()){
35 | printf(". ");
36 | debug("SHT[%d] REL[%d] rule [%.2d] executed\n", secnum, entry, rule);
37 | fprintf(logfp, " | SHT[%d] REL[%d] rule [%.2d] executed\n", secnum, entry, rule);
38 | }
39 | }
40 |
41 | int rel1(void)
42 | {
43 | if(rand() % 3 < 2)
44 | return 0;
45 |
46 | if(orcHDR->e_type == ET_REL){
47 | if(orcSHT->sh_type == SHT_REL)
48 | orcREL->r_offset = getElf_Half();
49 | else
50 | orcRELA->r_offset = getElf_Half();
51 | } else if(orcHDR->e_type == ET_EXEC || orcHDR->e_type == ET_DYN){
52 | if(orcSHT->sh_type == SHT_REL)
53 | orcREL->r_offset = getElf_Addr();
54 | else
55 | orcRELA->r_offset = getElf_Addr();
56 | } else
57 | return 0;
58 |
59 | fprintf(logfp, "(REL[%d]->r_offset = 0x"HEX")", entry, orcSHT->sh_type == SHT_REL ? orcREL->r_offset : orcRELA->r_offset);
60 |
61 | return 1;
62 | }
63 |
64 | int rel2(void)
65 | {
66 | if(rand() % 3 < 2)
67 | return 0;
68 |
69 | if(rand() % 4 < 3){ // 75% chance to only change its related Symbol Table index
70 | Elf_Section sym_ndx;
71 |
72 | if(rand() % 2)
73 | sym_ndx = rand() % orcHDR->e_shnum; // A random but valid Symbol Table index within the SHT
74 | else
75 | sym_ndx = getElf_Section();
76 |
77 | if(orcSHT->sh_type == SHT_REL)
78 | orcREL->r_info = ELF_R_INFO(sym_ndx, ELF_R_TYPE(orcREL->r_info));
79 | else
80 | orcRELA->r_info = ELF_R_INFO(sym_ndx, ELF_R_TYPE(orcRELA->r_info));
81 | } else {
82 | if(orcSHT->sh_type == SHT_REL)
83 | #if defined(__i386__) || defined(__ANDROID_API__)
84 | orcREL->r_info = getElf_Word();
85 | #elif defined(__x86_64__)
86 | orcREL->r_info = getElf_Xword();
87 | #endif
88 | else
89 | #if defined(__i386__) || defined(__ANDROID_API__)
90 | orcRELA->r_info = getElf_Word();
91 | #elif defined(__x86_64__)
92 | orcRELA->r_info = getElf_Xword();
93 | #endif
94 | }
95 |
96 | fprintf(logfp, "(REL[%d]->r_info = 0x"HEX")", entry, orcSHT->sh_type == SHT_REL ? orcREL->r_info : orcRELA->r_info);
97 |
98 | return 1;
99 | }
100 |
101 | int rel3(void)
102 | {
103 | if(orcSHT->sh_type == SHT_REL)
104 | return 0;
105 |
106 | if(rand() % 3 < 2)
107 | return 0;
108 |
109 | // r_addend is a Sword (Signed Word)
110 | if(rand() % 2){ // 75% chance to set r_addend to a negative number > 0x7fffffff
111 | #if defined(__x86_64__)
112 | if(rand() % 2)
113 | orcRELA->r_addend = 0x8000000000000000 + (rand() % 0x7fffffff);
114 | else
115 | #endif
116 | orcRELA->r_addend = 0x80000000 + (rand() % 0x7fffffff);
117 | } else {
118 | if(rand() % 2)
119 | orcRELA->r_addend = getElf_Word();
120 | else
121 | orcRELA->r_addend = getElf_Xword();
122 | }
123 |
124 | fprintf(logfp, "(REL[%d]->r_addend = 0x"HEX")", entry, orcRELA->r_addend);
125 |
126 | return 1;
127 | }
128 |
129 | void initialize_rel_funcs(void)
130 | {
131 | rel[1] = &rel1;
132 | rel[2] = &rel2;
133 | rel[3] = &rel3;
134 | }
135 |
--------------------------------------------------------------------------------
/jni/src/fuzz_sht.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Melkor - An ELF File Format Fuzzer
3 | * Copyright (C) 2014 Alejandro Hernandez H. (nitr0us)
4 | *
5 | * Mexico
6 | */
7 |
8 | #include "melkor.h"
9 | #include
10 |
11 | #define N_RULES_SHT 37 // Total of fuzzing rules defined for this metadata type
12 |
13 | // Array of function pointers. Index zero won't be used. The fuzzing rules start from index 1
14 | func_ptr sht[N_RULES_SHT + 1];
15 | int sh = 0; // Section Header. Used inside the for() loop in fuzz_sht() and will be used in the rules
16 |
17 | void initialize_sht_funcs(void) __attribute__((constructor));
18 |
19 | /* External vars */
20 | extern FILE *logfp;
21 | extern unsigned int mode; // Metadata to fuzz (parameters given in argv[])
22 | extern unsigned int quiet;
23 | extern unsigned int like_a, like_b;
24 | extern struct stat elfstatinfo;
25 | extern char *dirname_orcfname;
26 | extern char *elfptr, *orcptr;
27 | extern Elf_Ehdr *elfHDR;
28 | extern Elf_Ehdr *orcHDR;
29 | extern Elf_Shdr *elfSHT;
30 | extern Elf_Shdr *orcSHT;
31 | extern Elf_Shdr *orcOrigSHT;
32 | extern Elf_Off elfshstrtab_offset;
33 |
34 | void fuzz_sht()
35 | {
36 | int rule;
37 |
38 | for(sh = 0; sh < orcHDR->e_shnum; sh++, orcSHT++)
39 | for(rule = 1; rule <= N_RULES_SHT; rule++)
40 | if((rand() % like_a) < like_b)
41 | if(sht[rule]()){
42 | printf(". ");
43 | debug("SHT[%d] rule [%.2d] executed\n", sh, rule);
44 | fprintf(logfp, " | SHT[%d] rule [%.2d] executed\n", sh, rule);
45 | }
46 | }
47 |
48 | int sht1(void)
49 | {
50 | // Metadata dependencies
51 | switch(orcSHT->sh_type){
52 | case SHT_STRTAB:
53 | if(mode & STRS)
54 | if(rand() % 3 < 2)
55 | return 0;
56 | break;
57 | case SHT_NOTE:
58 | if(mode & NOTE)
59 | if(rand() % 3 < 2)
60 | return 0;
61 | break;
62 | case SHT_DYNAMIC:
63 | if(mode & DYN)
64 | if(rand() % 3 < 2)
65 | return 0;
66 | break;
67 | case SHT_SYMTAB:
68 | case SHT_DYNSYM:
69 | if(mode & SYM)
70 | if(rand() % 3 < 2)
71 | return 0;
72 | break;
73 | case SHT_RELA:
74 | case SHT_REL:
75 | if(mode & REL)
76 | if(rand() % 3 < 2)
77 | return 0;
78 | break;
79 | default:
80 | if(rand() % 2)
81 | return 0;
82 | }
83 |
84 | fuzzName();
85 |
86 | fprintf(logfp, "(SHT[%d]->sh_name = 0x%x)", sh, orcSHT->sh_name);
87 |
88 | return 1;
89 | }
90 |
91 | int sht2(void)
92 | {
93 | if(rand() % 3 == 0)
94 | return 0;
95 |
96 | orcSHT->sh_addr = getElf_Addr();
97 |
98 | fprintf(logfp, "(SHT[%d]->sh_addr = 0x"HEX")", sh, orcSHT->sh_addr);
99 |
100 | return 1;
101 | }
102 |
103 | int sht3(void)
104 | {
105 | // Metadata dependencies
106 | switch(orcSHT->sh_type){
107 | case SHT_STRTAB:
108 | if(mode & STRS)
109 | return 0;
110 | break;
111 | case SHT_NOTE:
112 | if(mode & NOTE)
113 | return 0;
114 | break;
115 | case SHT_DYNAMIC:
116 | if(mode & DYN)
117 | return 0;
118 | break;
119 | case SHT_SYMTAB:
120 | case SHT_DYNSYM:
121 | if(mode & (SYM | REL)) // In REL, sh_offset of the symbol table will be needed
122 | return 0;
123 | break;
124 | case SHT_RELA:
125 | case SHT_REL:
126 | if(mode & REL)
127 | return 0;
128 | break;
129 | default:
130 | if(rand() % 5 < 4) // 80% chance
131 | return 0;
132 | }
133 |
134 | orcSHT->sh_offset = getElf_Off();
135 |
136 | fprintf(logfp, "(SHT[%d]->sh_offset = 0x"HEX")", sh, orcSHT->sh_offset);
137 |
138 | return 1;
139 | }
140 |
141 | int sht4(void)
142 | {
143 | // Metadata dependencies
144 | switch(orcSHT->sh_type){
145 | case SHT_STRTAB:
146 | if(mode & STRS)
147 | if(rand() % 2) // 50% chance
148 | return 0;
149 | break;
150 | case SHT_NOTE:
151 | if(mode & NOTE)
152 | if(rand() % 2)
153 | return 0;
154 | break;
155 | case SHT_DYNAMIC:
156 | if(mode & DYN)
157 | if(rand() % 4 < 3)
158 | return 0;
159 | break;
160 | case SHT_SYMTAB:
161 | case SHT_DYNSYM:
162 | if(mode & SYM)
163 | if(rand() % 4 < 3)
164 | return 0;
165 | break;
166 | case SHT_RELA:
167 | case SHT_REL:
168 | if(mode & REL)
169 | if(rand() % 4 < 3)
170 | return 0;
171 | break;
172 | default:
173 | if(rand() % 3 < 2)
174 | return 0;
175 | }
176 |
177 | fuzzSize();
178 |
179 | fprintf(logfp, "(SHT[%d]->sh_size = 0x"HEX")", sh, orcSHT->sh_size);
180 |
181 | return 1;
182 | }
183 |
184 | int sht5(void)
185 | {
186 | fuzzAddrAlign();
187 |
188 | fprintf(logfp, "(SHT[%d]->sh_addralign = 0x"HEX")", sh, orcSHT->sh_addralign);
189 |
190 | return 1;
191 | }
192 |
193 | int sht6(void)
194 | {
195 | // Metadata dependencies
196 | switch(orcSHT->sh_type){
197 | case SHT_DYNAMIC:
198 | if(mode & DYN)
199 | if(rand() % 4 < 3)
200 | return 0;
201 | break;
202 | case SHT_SYMTAB:
203 | case SHT_DYNSYM:
204 | if(mode & SYM)
205 | if(rand() % 4 < 3)
206 | return 0;
207 | break;
208 | case SHT_RELA:
209 | case SHT_REL:
210 | if(mode & REL)
211 | if(rand() % 4 < 3)
212 | return 0;
213 | break;
214 | default:
215 | if(rand() % 2)
216 | return 0;
217 | }
218 |
219 | fuzzEntSize();
220 |
221 | fprintf(logfp, "(SHT[%d]->sh_entsize = 0x"HEX")", sh, orcSHT->sh_entsize);
222 |
223 | return 1;
224 | }
225 |
226 | int sht7(void)
227 | {
228 | // Metadata dependencies
229 | switch(orcSHT->sh_type){
230 | case SHT_STRTAB:
231 | if(mode & STRS)
232 | return 0;
233 | break;
234 | case SHT_NOTE:
235 | if(mode & NOTE)
236 | return 0;
237 | break;
238 | case SHT_DYNAMIC:
239 | if(mode & DYN)
240 | return 0;
241 | break;
242 | case SHT_SYMTAB:
243 | case SHT_DYNSYM:
244 | if(mode & (SYM | REL)) // In REL, sh_type of the symbol table will be needed
245 | return 0;
246 | break;
247 | case SHT_RELA:
248 | case SHT_REL:
249 | if(mode & REL)
250 | return 0;
251 | break;
252 | default:
253 | if(rand() % 4 < 3)
254 | return 0;
255 | }
256 |
257 | if(rand() % 4 < 3){ // 75% chance
258 | Elf_Word t;
259 |
260 | while((t = rand() % SHT_NUM)){
261 | switch(t){ // Metadata dependencies
262 | case SHT_STRTAB:
263 | if(mode & STRS)
264 | continue;
265 | break;
266 | case SHT_NOTE:
267 | if(mode & NOTE)
268 | continue;
269 | break;
270 | case SHT_DYNAMIC:
271 | if(mode & DYN)
272 | continue;
273 | break;
274 | case SHT_SYMTAB:
275 | case SHT_DYNSYM:
276 | if(mode & (SYM | REL)) // In REL, sh_type of the symbol table will be needed
277 | continue;
278 | break;
279 | case SHT_REL:
280 | case SHT_RELA:
281 | if(mode & REL)
282 | continue;
283 | break;
284 | default:
285 | break;
286 | }
287 |
288 | break;
289 | }
290 |
291 | orcSHT->sh_type = t;
292 | } else
293 | orcSHT->sh_type = getElf_Word();
294 |
295 | fprintf(logfp, "(SHT[%d]->sh_type = 0x%x)", sh, orcSHT->sh_type);
296 |
297 | return 1;
298 | }
299 |
300 | int sht8(void)
301 | {
302 | // Metadata dependencies
303 | switch(orcSHT->sh_type){
304 | case SHT_STRTAB:
305 | if(mode & STRS)
306 | return 0;
307 | break;
308 | case SHT_NOTE:
309 | if(mode & NOTE)
310 | return 0;
311 | break;
312 | case SHT_DYNAMIC:
313 | if(mode & DYN)
314 | return 0;
315 | break;
316 | case SHT_SYMTAB:
317 | case SHT_DYNSYM:
318 | if(mode & (SYM | REL)) // In REL, sh_type of the symbol table will be needed
319 | return 0;
320 | break;
321 | case SHT_RELA:
322 | case SHT_REL:
323 | if(mode & REL)
324 | return 0;
325 | break;
326 | default:
327 | if(rand() % 5 < 4) // 80% chance
328 | return 0;
329 | }
330 |
331 | int r = rand();
332 |
333 | if(r % 4 == 0)
334 | orcSHT->sh_type = SHT_LOPROC + 1;
335 | else if(r % 4 == 1)
336 | orcSHT->sh_type = SHT_HIPROC;
337 | else if(r % 4 == 2)
338 | orcSHT->sh_type = SHT_LOUSER + 1;
339 | else
340 | orcSHT->sh_type = SHT_HIUSER;
341 |
342 | fprintf(logfp, "(SHT[%d]->sh_type = 0x%x)", sh, orcSHT->sh_type);
343 |
344 | return 1;
345 | }
346 |
347 | int sht9(void)
348 | {
349 | if(orcSHT->sh_type != SHT_NULL)
350 | return 0;
351 |
352 | fuzzName();
353 | fuzzSize();
354 | fuzzEntSize();
355 | orcSHT->sh_offset = getElf_Off();
356 |
357 | fprintf(logfp, "(SHT[%d]->sh_name = 0x%x,", sh, orcSHT->sh_name);
358 | fprintf(logfp, " sh_offset = 0x"HEX",", orcSHT->sh_offset);
359 | fprintf(logfp, " sh_size = 0x"HEX",", orcSHT->sh_size);
360 | fprintf(logfp, " sh_entsize = 0x"HEX")", orcSHT->sh_entsize);
361 |
362 | return 1;
363 | }
364 |
365 | int sht10(void)
366 | {
367 | fuzzFlags();
368 |
369 | fprintf(logfp, "(SHT[%d]->sh_flags = 0x"HEX")", sh, orcSHT->sh_flags);
370 |
371 | return 1;
372 | }
373 | int sht11(void)
374 | {
375 | if(orcSHT->sh_type != SHT_DYNAMIC &&
376 | orcSHT->sh_type != SHT_HASH &&
377 | orcSHT->sh_type != SHT_GNU_HASH)
378 | return 0;
379 |
380 | Elf_Word l;
381 |
382 | if(rand() % 2)
383 | orcSHT->sh_info = 1 + (rand() % (orcHDR->e_shnum - 1));
384 | else
385 | orcSHT->sh_info = getElf_Word();
386 |
387 | if(orcSHT->sh_type == SHT_DYNAMIC){
388 | if(mode & DYN){
389 | if(rand() % 2){
390 | fprintf(logfp, "(SHT[%d]->sh_info = 0x%x)", sh, orcSHT->sh_info);
391 |
392 | return 1;
393 | } else {
394 | if(rand() % 4 < 3){
395 | while((l = 1 + (rand() % (orcHDR->e_shnum - 1))))
396 | if(orcOrigSHT[l].sh_type != SHT_STRTAB)
397 | break;
398 | } else
399 | l = (Elf_Word) getElf_Half();
400 |
401 | orcSHT->sh_link = l;
402 | }
403 | } else {
404 | if(rand() % 2)
405 | orcSHT->sh_link = 1 + (rand() % (orcHDR->e_shnum - 1));
406 | else
407 | orcSHT->sh_link = (Elf_Word) getElf_Half();
408 | }
409 | } else { // HASH
410 | if(rand() % 4 < 3){
411 | while((l = 1 + (rand() % (orcHDR->e_shnum - 1))))
412 | if(orcOrigSHT[l].sh_type != SHT_SYMTAB && orcOrigSHT[l].sh_type != SHT_DYNSYM)
413 | break;
414 | } else
415 | l = (Elf_Word) getElf_Half();
416 |
417 | orcSHT->sh_link = l;
418 | }
419 |
420 | fprintf(logfp, "(SHT[%d]->sh_link = 0x%x,", sh, orcSHT->sh_link);
421 | fprintf(logfp, " sh_info = 0x%x)", orcSHT->sh_info);
422 |
423 | return 1;
424 | }
425 |
426 | int sht12(void)
427 | {
428 | if(orcSHT->sh_type != SHT_REL &&
429 | orcSHT->sh_type != SHT_RELA)
430 | return 0;
431 |
432 | Elf_Word l;
433 |
434 | if(mode & REL){
435 | if(rand() % 2){
436 | if(rand() % 2)
437 | orcSHT->sh_info = 1 + (rand() % (orcHDR->e_shnum - 1));
438 | else
439 | orcSHT->sh_info = getElf_Word();
440 |
441 | fprintf(logfp, "(SHT[%d]->sh_info = 0x%x)", sh, orcSHT->sh_info);
442 |
443 | return 1;
444 | } else
445 | return 0;
446 | } else {
447 | if(rand() % 4 < 3){
448 | while((l = 1 + (rand() % (orcHDR->e_shnum - 1))))
449 | if(orcOrigSHT[l].sh_type != SHT_SYMTAB && orcOrigSHT[l].sh_type != SHT_DYNSYM)
450 | break;
451 | } else
452 | l = (Elf_Word) getElf_Half();
453 |
454 | orcSHT->sh_link = l;
455 |
456 | if(rand() % 2)
457 | orcSHT->sh_info = 1 + (rand() % (orcHDR->e_shnum - 1));
458 | else
459 | orcSHT->sh_info = getElf_Word();
460 | }
461 |
462 | fprintf(logfp, "(SHT[%d]->sh_link = 0x%x,", sh, orcSHT->sh_link);
463 | fprintf(logfp, " sh_info = 0x%x)", orcSHT->sh_info);
464 |
465 | return 1;
466 | }
467 |
468 | int sht13(void)
469 | {
470 | if(orcSHT->sh_type != SHT_SYMTAB &&
471 | orcSHT->sh_type != SHT_DYNSYM)
472 | return 0;
473 |
474 | if(mode & REL) // In REL, sh_link is the associated symbol table
475 | if(rand() % 3 < 2)
476 | return 0;
477 |
478 | if(mode & SYM)
479 | if(rand() % 2)
480 | return 0;
481 |
482 | if(rand() % 2){
483 | if(rand() % 2)
484 | orcSHT->sh_info = 1 + (rand() % (orcHDR->e_shnum - 1));
485 | else
486 | orcSHT->sh_info = (Elf_Word) getElf_Half();
487 |
488 | Elf_Word l;
489 |
490 | if(rand() % 4 < 3){
491 | while((l = 1 + (rand() % (orcHDR->e_shnum - 1))))
492 | if(orcOrigSHT[l].sh_type != SHT_STRTAB)
493 | break;
494 | } else
495 | l = (Elf_Word) getElf_Half();
496 |
497 | orcSHT->sh_link = l;
498 | } else
499 | return 0;
500 |
501 | fprintf(logfp, "(SHT[%d]->sh_link = 0x%x,", sh, orcSHT->sh_link);
502 | fprintf(logfp, " sh_info = 0x%x)", orcSHT->sh_info);
503 |
504 | return 1;
505 | }
506 |
507 | int sht14(void)
508 | {
509 | if(orcSHT->sh_type != SHT_NOBITS)
510 | return 0;
511 |
512 | fuzzFlags();
513 | fuzzSize();
514 |
515 | fprintf(logfp, "(SHT[%d]->sh_flags = 0x"HEX",", sh, orcSHT->sh_flags);
516 | fprintf(logfp, " sh_size = 0x"HEX")", orcSHT->sh_size);
517 |
518 | return 1;
519 | }
520 |
521 | int sht15(void)
522 | {
523 | Elf_Section ndx;
524 |
525 | if(!(ndx = findSectionIndexByName(".data")))
526 | return 0;
527 |
528 | // Return if not the current section header being fuzzed
529 | if(ndx != sh)
530 | return 0;
531 |
532 | if(rand() % 2){
533 | if(rand() % 2){
534 | Elf_Word t;
535 |
536 | while((t = rand() % SHT_NUM)){
537 | switch(t){
538 | case SHT_STRTAB:
539 | if(mode & STRS)
540 | continue;
541 | break;
542 | case SHT_NOTE:
543 | if(mode & NOTE)
544 | continue;
545 | break;
546 | case SHT_DYNAMIC:
547 | if(mode & DYN)
548 | continue;
549 | break;
550 | case SHT_SYMTAB:
551 | case SHT_DYNSYM:
552 | if(mode & (SYM | REL)) // In REL, sh_type of the symbol table will be needed
553 | continue;
554 | break;
555 | case SHT_REL:
556 | case SHT_RELA:
557 | if(mode & REL)
558 | continue;
559 | break;
560 | default:
561 | break;
562 | }
563 |
564 | break;
565 | }
566 |
567 | orcSHT->sh_type = t;
568 | } else
569 | orcSHT->sh_type = getElf_Word();
570 | }
571 |
572 | fuzzFlags();
573 | fuzzSize();
574 |
575 | fprintf(logfp, "(SHT[%d]->sh_type = 0x%x,", sh, orcSHT->sh_type);
576 | fprintf(logfp, " sh_size = 0x"HEX",", orcSHT->sh_size);
577 | fprintf(logfp, " sh_flags = 0x"HEX")", orcSHT->sh_flags);
578 |
579 | return 1;
580 | }
581 |
582 | int sht16(void)
583 | {
584 | if(orcSHT->sh_type != SHT_HASH &&
585 | orcSHT->sh_type != SHT_GNU_HASH)
586 | return 0;
587 |
588 | fuzzSize();
589 | fuzzEntSize();
590 | fuzzFlags();
591 | fuzzAddrAlign();
592 |
593 | fprintf(logfp, "(SHT[%d]->sh_size = 0x"HEX",", sh, orcSHT->sh_size);
594 | fprintf(logfp, " sh_flags = 0x"HEX",", orcSHT->sh_flags);
595 | fprintf(logfp, " sh_entsize = 0x"HEX",", orcSHT->sh_entsize);
596 | fprintf(logfp, " sh_addralign = 0x"HEX")", orcSHT->sh_addralign);
597 |
598 | return 1;
599 | }
600 |
601 | int sht17(void)
602 | {
603 | if(sh == 0) // Avoid the first entry of the SHT
604 | return 0;
605 |
606 | Elf_Section dar = findSectionIndexByName(".debug_aranges");
607 | Elf_Section din = findSectionIndexByName(".debug_info");
608 | Elf_Section dab = findSectionIndexByName(".debug_abbrev");
609 | Elf_Section dli = findSectionIndexByName(".debug_line");
610 | Elf_Section dst = findSectionIndexByName(".debug_str");
611 |
612 | if(dar != sh && din != sh && dab != sh && dli != sh && dst != sh)
613 | return 0;
614 |
615 | if(rand() % 2){
616 | if(rand() % 2){
617 | Elf_Word t;
618 |
619 | while((t = rand() % SHT_NUM)){
620 | switch(t){
621 | case SHT_STRTAB:
622 | if(mode & STRS)
623 | continue;
624 | break;
625 | case SHT_NOTE:
626 | if(mode & NOTE)
627 | continue;
628 | break;
629 | case SHT_DYNAMIC:
630 | if(mode & DYN)
631 | continue;
632 | break;
633 | case SHT_SYMTAB:
634 | case SHT_DYNSYM:
635 | if(mode & (SYM | REL)) // In REL, sh_type of the symbol table will be needed
636 | continue;
637 | break;
638 | case SHT_REL:
639 | case SHT_RELA:
640 | if(mode & REL)
641 | continue;
642 | break;
643 | default:
644 | break;
645 | }
646 |
647 | break;
648 | }
649 |
650 | orcSHT->sh_type = t;
651 | } else
652 | orcSHT->sh_type = getElf_Word();
653 | }
654 |
655 | fuzzFlags();
656 | fuzzSize();
657 | fuzzEntSize();
658 |
659 | fprintf(logfp, "(SHT[%d]->sh_type = 0x%x,", sh, orcSHT->sh_type);
660 | fprintf(logfp, " sh_flags = 0x"HEX",", orcSHT->sh_flags);
661 | fprintf(logfp, " sh_size = 0x"HEX",", orcSHT->sh_size);
662 | fprintf(logfp, " sh_entsize = 0x"HEX")", orcSHT->sh_entsize);
663 |
664 | return 1;
665 | }
666 |
667 | int sht18(void)
668 | {
669 | if(orcSHT->sh_type != SHT_DYNAMIC)
670 | return 0;
671 |
672 | orcSHT->sh_flags &= ~SHF_ALLOC;
673 | orcSHT->sh_flags &= ~SHF_WRITE;
674 |
675 | fprintf(logfp, "(SHT[%d]->sh_flags = 0x"HEX")", sh, orcSHT->sh_flags);
676 |
677 | return 1;
678 | }
679 |
680 | int sht19(void)
681 | {
682 | if(sh == 0) // Avoid the first entry of the SHT
683 | return 0;
684 |
685 | Elf_Section rodata = findSectionIndexByName(".rodata");
686 | Elf_Section rodata1 = findSectionIndexByName(".rodata1");
687 |
688 | if(rodata != sh && rodata1 != sh)
689 | return 0;
690 |
691 | if(rand() % 2){
692 | if(rand() % 2){
693 | Elf_Word t;
694 |
695 | while((t = rand() % SHT_NUM)){
696 | switch(t){
697 | case SHT_STRTAB:
698 | if(mode & STRS)
699 | continue;
700 | break;
701 | case SHT_NOTE:
702 | if(mode & NOTE)
703 | continue;
704 | break;
705 | case SHT_DYNAMIC:
706 | if(mode & DYN)
707 | continue;
708 | break;
709 | case SHT_SYMTAB:
710 | case SHT_DYNSYM:
711 | if(mode & (SYM | REL)) // In REL, sh_type of the symbol table will be needed
712 | continue;
713 | break;
714 | case SHT_REL:
715 | case SHT_RELA:
716 | if(mode & REL)
717 | continue;
718 | break;
719 | default:
720 | break;
721 | }
722 |
723 | break;
724 | }
725 |
726 | orcSHT->sh_type = t;
727 | } else
728 | orcSHT->sh_type = getElf_Word();
729 | }
730 |
731 | fuzzFlags();
732 | fuzzSize();
733 | fuzzEntSize();
734 |
735 | fprintf(logfp, "(SHT[%d]->sh_type = 0x%x,", sh, orcSHT->sh_type);
736 | fprintf(logfp, " sh_flags = 0x"HEX",", orcSHT->sh_flags);
737 | fprintf(logfp, " sh_size = 0x"HEX",", orcSHT->sh_size);
738 | fprintf(logfp, " sh_entsize = 0x"HEX")", orcSHT->sh_entsize);
739 |
740 | return 1;
741 | }
742 |
743 | int sht20(void)
744 | {
745 | if(orcSHT->sh_type != SHT_NOTE)
746 | return 0;
747 |
748 | if(mode & NOTE)
749 | if(rand() % 2)
750 | return 0;
751 |
752 | #if defined(__i386__) || defined(__ANDROID_API__)
753 | Elf_Word s;
754 | #elif defined(__x86_64__)
755 | Elf_Xword s;
756 | #endif
757 |
758 | int r = rand();
759 |
760 | if(r % 3 == 0) // If running in 64 bits, set a size modulo the 32-bits struct's size and viceversa
761 | s = sizeof(Elf_Nhdr);
762 | else if(r % 3 == 1){
763 | while((s = rand() & 0x00ffffff))
764 | if(s % 4 != 0)
765 | break;
766 | } else // Just the size of the header of the running platform
767 | s = sizeof(Elf_Nhdr);
768 |
769 | orcSHT->sh_size = s;
770 |
771 | fuzzFlags();
772 | fuzzEntSize();
773 | fuzzAddrAlign();
774 |
775 | fprintf(logfp, "(SHT[%d]->sh_size = 0x"HEX",", sh, orcSHT->sh_size);
776 | fprintf(logfp, " sh_flags = 0x"HEX",", orcSHT->sh_flags);
777 | fprintf(logfp, " sh_entsize = 0x"HEX",", orcSHT->sh_entsize);
778 | fprintf(logfp, " sh_addralign = 0x"HEX")", orcSHT->sh_addralign);
779 |
780 | return 1;
781 | }
782 |
783 | int sht21(void)
784 | {
785 | if(orcSHT->sh_type != SHT_STRTAB)
786 | return 0;
787 |
788 | if(mode & STRS)
789 | if(rand() % 2)
790 | return 0;
791 |
792 | fuzzFlags();
793 | fuzzSize();
794 | fuzzEntSize();
795 | fuzzAddrAlign();
796 |
797 | fprintf(logfp, "(SHT[%d]->sh_size = 0x"HEX",", sh, orcSHT->sh_size);
798 | fprintf(logfp, " sh_flags = 0x"HEX",", orcSHT->sh_flags);
799 | fprintf(logfp, " sh_entsize = 0x"HEX",", orcSHT->sh_entsize);
800 | fprintf(logfp, " sh_addralign = 0x"HEX")", orcSHT->sh_addralign);
801 |
802 | return 1;
803 | }
804 |
805 | int sht22(void)
806 | {
807 | if(orcSHT->sh_type != SHT_SYMTAB &&
808 | orcSHT->sh_type != SHT_DYNSYM)
809 | return 0;
810 |
811 | if(mode & SYM)
812 | if(rand() % 4 < 3)
813 | return 0;
814 |
815 | fuzzFlags();
816 | fuzzSize();
817 | fuzzEntSize();
818 | fuzzAddrAlign();
819 |
820 | fprintf(logfp, "(SHT[%d]->sh_size = 0x"HEX",", sh, orcSHT->sh_size);
821 | fprintf(logfp, " sh_flags = 0x"HEX",", orcSHT->sh_flags);
822 | fprintf(logfp, " sh_entsize = 0x"HEX",", orcSHT->sh_entsize);
823 | fprintf(logfp, " sh_addralign = 0x"HEX")", orcSHT->sh_addralign);
824 |
825 | return 1;
826 | }
827 |
828 | int sht23(void)
829 | {
830 | if(sh == 0) // Avoid the first entry of the SHT
831 | return 0;
832 |
833 | Elf_Section ndx;
834 |
835 | if(!(ndx = findSectionIndexByName(".text")))
836 | return 0;
837 |
838 | // Return if not the current section header being fuzzed
839 | if(ndx != sh)
840 | return 0;
841 |
842 | if(rand() % 2){
843 | Elf_Word t;
844 |
845 | while((t = rand() % SHT_NUM)){
846 | switch(t){
847 | case SHT_PROGBITS:
848 | continue;
849 | break;
850 | case SHT_STRTAB:
851 | if(mode & STRS)
852 | continue;
853 | break;
854 | case SHT_NOTE:
855 | if(mode & NOTE)
856 | continue;
857 | break;
858 | case SHT_DYNAMIC:
859 | if(mode & DYN)
860 | continue;
861 | break;
862 | case SHT_SYMTAB:
863 | case SHT_DYNSYM:
864 | if(mode & (SYM | REL)) // In REL, sh_type of the symbol table will be needed
865 | continue;
866 | break;
867 | case SHT_REL:
868 | case SHT_RELA:
869 | if(mode & REL)
870 | continue;
871 | break;
872 | default:
873 | break;
874 | }
875 |
876 | break;
877 | }
878 |
879 | orcSHT->sh_type = t;
880 | } else
881 | orcSHT->sh_type = getElf_Word();
882 |
883 | int r = rand();
884 |
885 | if(r % 3 == 0){
886 | orcSHT->sh_flags &= ~SHF_ALLOC;
887 | orcSHT->sh_flags &= ~SHF_EXECINSTR;
888 | } else if(r % 3 == 1)
889 | orcSHT->sh_flags = getElf_Word();
890 | else
891 | orcSHT->sh_flags = 0x00;
892 |
893 | fprintf(logfp, "(SHT[%d]->sh_type = 0x%x,", sh, orcSHT->sh_type);
894 | fprintf(logfp, " sh_flags = 0x"HEX")", orcSHT->sh_flags);
895 |
896 | return 1;
897 | }
898 |
899 | int sht24(void)
900 | {
901 | if(sh == 0) // Avoid the first entry of the SHT
902 | return 0;
903 |
904 | Elf_Section init = findSectionIndexByName(".init");
905 | Elf_Section fini = findSectionIndexByName(".fini");
906 |
907 | if(init != sh && fini != sh)
908 | return 0;
909 |
910 | if(rand() % 2){
911 | Elf_Word t;
912 |
913 | while((t = rand() % SHT_NUM)){
914 | switch(t){
915 | case SHT_PROGBITS:
916 | continue;
917 | break;
918 | case SHT_STRTAB:
919 | if(mode & STRS)
920 | continue;
921 | break;
922 | case SHT_NOTE:
923 | if(mode & NOTE)
924 | continue;
925 | break;
926 | case SHT_DYNAMIC:
927 | if(mode & DYN)
928 | continue;
929 | break;
930 | case SHT_SYMTAB:
931 | case SHT_DYNSYM:
932 | if(mode & (SYM | REL)) // In REL, sh_type of the symbol table will be needed
933 | continue;
934 | break;
935 | case SHT_REL:
936 | case SHT_RELA:
937 | if(mode & REL)
938 | continue;
939 | break;
940 | default:
941 | break;
942 | }
943 |
944 | break;
945 | }
946 |
947 | orcSHT->sh_type = t;
948 | } else
949 | orcSHT->sh_type = getElf_Word();
950 |
951 | int r = rand();
952 |
953 | if(r % 3 == 0){
954 | orcSHT->sh_flags &= ~SHF_ALLOC;
955 | orcSHT->sh_flags &= ~SHF_EXECINSTR;
956 | } else if(r % 3 == 1)
957 | orcSHT->sh_flags = getElf_Word();
958 | else
959 | orcSHT->sh_flags = 0x00;
960 |
961 | fprintf(logfp, "(SHT[%d]->sh_type = 0x%x,", sh, orcSHT->sh_type);
962 | fprintf(logfp, " sh_flags = 0x"HEX")", orcSHT->sh_flags);
963 |
964 | return 1;
965 | }
966 |
967 | int sht25(void)
968 | {
969 | if(sh == 0) // Avoid the first entry of the SHT
970 | return 0;
971 |
972 | Elf_Section interp;
973 |
974 | if(!(interp = findSectionIndexByName(".interp")))
975 | return 0;
976 |
977 | if(interp != sh)
978 | return 0;
979 |
980 | if(rand() % 2)
981 | orcSHT->sh_type = SHT_NULL;
982 |
983 | if(rand() % 2)
984 | orcSHT->sh_flags &= ~SHF_ALLOC;
985 | else
986 | orcSHT->sh_flags = 0x00;
987 |
988 | // Using the original sh_offset of the ELF. sh_offset in the ORC might be already fuzzed
989 | strncpy(orcptr + elfSHT[interp].sh_offset, dirname_orcfname, strlen(dirname_orcfname));
990 | *(orcptr + elfSHT[interp].sh_offset + strlen(dirname_orcfname)) = '\0';
991 |
992 | fprintf(logfp, "(SHT[%d]->sh_type = 0x%x,", sh, orcSHT->sh_type);
993 | fprintf(logfp, " sh_flags = 0x"HEX",", orcSHT->sh_flags);
994 | fprintf(logfp, " .interp = %s)", orcptr + elfSHT[interp].sh_offset);
995 |
996 | return 1;
997 | }
998 |
999 | int sht26(void)
1000 | {
1001 | if(sh == 0) // Avoid the first entry of the SHT
1002 | return 0;
1003 |
1004 | Elf_Section got = findSectionIndexByName(".got");
1005 |
1006 | if(got != sh)
1007 | return 0;
1008 |
1009 | orcSHT->sh_flags &= ~SHF_WRITE;
1010 |
1011 | fprintf(logfp, "(SHT[%d]->sh_flags = 0x"HEX")", sh, orcSHT->sh_flags);
1012 |
1013 | return 1;
1014 | }
1015 |
1016 | int sht27(void)
1017 | {
1018 | if(sh == 0) // Avoid the first entry of the SHT
1019 | return 0;
1020 |
1021 | Elf_Section plt = findSectionIndexByName(".plt");
1022 |
1023 | if(plt != sh)
1024 | return 0;
1025 |
1026 | if(rand() % 4 < 3){ // 75% chance
1027 | orcSHT->sh_flags &= ~SHF_EXECINSTR;
1028 |
1029 | fprintf(logfp, "(SHT[%d]->sh_flags = 0x"HEX")", sh, orcSHT->sh_flags);
1030 |
1031 | return 1;
1032 | } else { // Binary patch: the second jmp instruction in the PLT
1033 | unsigned int jmp_asm;
1034 | int r = rand();
1035 |
1036 | // The 1st jmp in PLT is 6 bytes length in x86 and x86_64
1037 | *(orcptr + elfSHT[plt].sh_offset + 6) = 0xff; // jmp opcode
1038 | *(orcptr + elfSHT[plt].sh_offset + 7) = 0x25; // jmp opcode
1039 |
1040 | if(r % 4 == 0) // jmp to the original entrypoint
1041 | jmp_asm = (unsigned int) elfHDR->e_entry;
1042 | else if(r % 4 == 1){ // jmp to _init (".init".sh_addr)
1043 | Elf_Section init;
1044 |
1045 | if(!(init = findSectionIndexByName(".init")))
1046 | return 0;
1047 |
1048 | jmp_asm = (unsigned int) elfSHT[init].sh_addr;
1049 | } else if(r % 4 == 2){ // jmp to _fini (".fini".sh_addr)
1050 | Elf_Section fini;
1051 |
1052 | if(!(fini = findSectionIndexByName(".fini")))
1053 | return 0;
1054 |
1055 | jmp_asm = (unsigned int) elfSHT[fini].sh_addr;
1056 | } else { // jmp to a semi-random address
1057 | jmp_asm = (unsigned int) getElf_Addr();
1058 | if(rand() % 2)
1059 | jmp_asm = SWAP32(jmp_asm); // little-endian conversion, just for phun ;D
1060 | }
1061 |
1062 | memcpy(orcptr + elfSHT[plt].sh_offset + 8, &jmp_asm, sizeof(jmp_asm));
1063 |
1064 | fprintf(logfp, "(SHT[%d]->(sh_offset + 6) = jmp 0x%x)", sh, jmp_asm);
1065 |
1066 | return 1;
1067 | }
1068 | }
1069 |
1070 | int sht28(void)
1071 | {
1072 | if(orcSHT->sh_type != SHT_STRTAB)
1073 | return 0;
1074 |
1075 | if(sh == elfHDR->e_shstrndx)
1076 | return 0;
1077 |
1078 | if(rand() % 2){
1079 | if(mode & STRS)
1080 | return 0;
1081 |
1082 | if(mode & REL) // If REL is fuzzed, the sh_offset of the string tab will be needed
1083 | if(rand() % 3 < 2)
1084 | return 0;
1085 |
1086 | orcSHT->sh_offset = elfstatinfo.st_size; // Pointing at the end of the file
1087 | orcSHT->sh_size = 0x1337;
1088 | } else {
1089 | if(mode & STRS)
1090 | if(rand() % 2)
1091 | return 0;
1092 |
1093 | orcSHT->sh_size = 0;
1094 | }
1095 |
1096 | fprintf(logfp, "(SHT[%d]->sh_offset = 0x"HEX",", sh, orcSHT->sh_offset);
1097 | fprintf(logfp, " sh_size = 0x"HEX")", orcSHT->sh_size);
1098 |
1099 | return 1;
1100 | }
1101 |
1102 | int sht29(void)
1103 | {
1104 | if(orcSHT->sh_type != SHT_HASH &&
1105 | orcSHT->sh_type != SHT_GNU_HASH)
1106 | return 0;
1107 |
1108 | if(rand() % 4 < 3)
1109 | return 0;
1110 |
1111 | orcSHT->sh_type = getElf_Word();
1112 |
1113 | fprintf(logfp, "(SHT[%d]->sh_type = 0x%x)", sh, orcSHT->sh_type);
1114 |
1115 | return 1;
1116 | }
1117 |
1118 | int sht30(void)
1119 | {
1120 | if(sh == 0) // Avoid the first entry of the SHT
1121 | return 0;
1122 |
1123 | // Metadata dependencies
1124 | switch(orcSHT->sh_type){
1125 | case SHT_STRTAB:
1126 | if(mode & STRS)
1127 | if(rand() % 3 < 2)
1128 | return 0;
1129 | break;
1130 | case SHT_NOTE:
1131 | if(mode & NOTE)
1132 | if(rand() % 3 < 2)
1133 | return 0;
1134 | break;
1135 | case SHT_DYNAMIC:
1136 | if(mode & DYN)
1137 | if(rand() % 3 < 2)
1138 | return 0;
1139 | break;
1140 | case SHT_SYMTAB:
1141 | case SHT_DYNSYM:
1142 | if(mode & SYM)
1143 | if(rand() % 3 < 2)
1144 | return 0;
1145 | break;
1146 | case SHT_RELA:
1147 | case SHT_REL:
1148 | if(mode & REL)
1149 | if(rand() % 3 < 2)
1150 | return 0;
1151 | break;
1152 | default:
1153 | if(rand() % 4 < 3)
1154 | return 0;
1155 | }
1156 |
1157 | Elf_Section text = findSectionIndexByName(".text");
1158 | Elf_Section data = findSectionIndexByName(".data");
1159 | Elf_Section got = findSectionIndexByName(".got");
1160 | Elf_Section bss = findSectionIndexByName(".bss");
1161 | Elf_Section gotplt = findSectionIndexByName(".got.plt");
1162 |
1163 | int r = rand();
1164 |
1165 | if(r % 5 == 0){
1166 | if(!text)
1167 | return 0;
1168 |
1169 | orcSHT->sh_name = elfSHT[text].sh_name;
1170 | } else if(r % 5 == 1){
1171 | if(!data)
1172 | return 0;
1173 |
1174 | orcSHT->sh_name = elfSHT[data].sh_name;
1175 | } else if(r % 5 == 2){
1176 | if(!got)
1177 | return 0;
1178 |
1179 | orcSHT->sh_name = elfSHT[got].sh_name;
1180 | } else if(r % 5 == 3){
1181 | if(!bss)
1182 | return 0;
1183 |
1184 | orcSHT->sh_name = elfSHT[bss].sh_name;
1185 | } else {
1186 | if(!gotplt)
1187 | return 0;
1188 |
1189 | orcSHT->sh_name = elfSHT[gotplt].sh_name;
1190 | }
1191 |
1192 | fprintf(logfp, "(SHT[%d]->sh_name = 0x%x)", sh, orcSHT->sh_name);
1193 |
1194 | return 1;
1195 | }
1196 |
1197 | int sht31(void)
1198 | {
1199 | // Metadata dependencies
1200 | switch(orcSHT->sh_type){
1201 | case SHT_STRTAB:
1202 | if(mode & STRS)
1203 | return 0;
1204 | break;
1205 | case SHT_NOTE:
1206 | if(mode & NOTE)
1207 | return 0;
1208 | break;
1209 | case SHT_DYNAMIC:
1210 | if(mode & DYN)
1211 | return 0;
1212 | break;
1213 | case SHT_SYMTAB:
1214 | case SHT_DYNSYM:
1215 | if(mode & (SYM | REL)) // In REL, sh_type of the symbol table will be needed
1216 | return 0;
1217 | break;
1218 | case SHT_RELA:
1219 | case SHT_REL:
1220 | if(mode & REL)
1221 | return 0;
1222 | break;
1223 | default:
1224 | if(rand() % 5 < 4) // 80% chance
1225 | return 0;
1226 | }
1227 |
1228 | if(rand() % 2)
1229 | orcSHT->sh_type = SHT_LOOS;
1230 | else
1231 | orcSHT->sh_type = SHT_HIOS;
1232 |
1233 | fprintf(logfp, "(SHT[%d]->sh_type = 0x%x)", sh, orcSHT->sh_type);
1234 |
1235 | return 1;
1236 | }
1237 |
1238 | int sht32(void)
1239 | {
1240 | orcSHT->sh_flags |= SHF_MASKOS;
1241 |
1242 | fprintf(logfp, "(SHT[%d]->sh_flags = 0x"HEX")", sh, orcSHT->sh_flags);
1243 |
1244 | return 1;
1245 | }
1246 |
1247 | int sht33(void)
1248 | {
1249 | // Metadata dependencies
1250 | switch(orcSHT->sh_type){
1251 | case SHT_STRTAB:
1252 | if(mode & STRS)
1253 | return 0;
1254 | break;
1255 | case SHT_NOTE:
1256 | if(mode & NOTE)
1257 | return 0;
1258 | break;
1259 | case SHT_DYNAMIC:
1260 | if(mode & DYN)
1261 | return 0;
1262 | break;
1263 | case SHT_SYMTAB:
1264 | case SHT_DYNSYM:
1265 | if(mode & (SYM | REL)) // In REL, sh_type of the symbol table will be needed
1266 | return 0;
1267 | break;
1268 | case SHT_RELA:
1269 | case SHT_REL:
1270 | if(mode & REL)
1271 | return 0;
1272 | break;
1273 | default:
1274 | if(rand() % 5 < 4) // 80% chance
1275 | return 0;
1276 | }
1277 |
1278 | int r = rand();
1279 |
1280 | if(r % 6 == 0)
1281 | orcSHT->sh_type = SHT_GNU_ATTRIBUTES;
1282 | else if(r % 6 == 1)
1283 | orcSHT->sh_type = SHT_GNU_HASH;
1284 | else if(r % 6 == 2)
1285 | orcSHT->sh_type = SHT_GNU_LIBLIST;
1286 | else if(r % 6 == 3)
1287 | orcSHT->sh_type = SHT_GNU_verdef;
1288 | else if(r % 6 == 4)
1289 | orcSHT->sh_type = SHT_GNU_verneed;
1290 | else
1291 | orcSHT->sh_type = SHT_GNU_versym;
1292 |
1293 | fprintf(logfp, "(SHT[%d]->sh_type = 0x%x)", sh, orcSHT->sh_type);
1294 |
1295 | return 1;
1296 | }
1297 |
1298 | int sht34(void)
1299 | {
1300 | int fuzzed = 0;
1301 |
1302 | if(orcSHT->sh_flags & SHF_WRITE){
1303 | orcSHT->sh_flags &= ~SHF_ALLOC;
1304 | fuzzed++;
1305 | }
1306 |
1307 | if(orcSHT->sh_flags & SHF_EXECINSTR){
1308 | orcSHT->sh_flags &= ~SHF_ALLOC;
1309 | fuzzed++;
1310 | }
1311 |
1312 | if(!fuzzed)
1313 | return 0;
1314 |
1315 | fprintf(logfp, "(SHT[%d]->sh_flags = 0x"HEX")", sh, orcSHT->sh_flags);
1316 |
1317 | return 1;
1318 | }
1319 |
1320 | int sht35(void)
1321 | {
1322 | if(sh == 0) // Avoid the first entry of the SHT
1323 | return 0;
1324 |
1325 | if(orcSHT->sh_type != SHT_INIT_ARRAY &&
1326 | orcSHT->sh_type != SHT_FINI_ARRAY)
1327 | return 0;
1328 |
1329 | if(rand() % 2)
1330 | return 0;
1331 |
1332 | Elf_Addr addr;
1333 | int r = rand();
1334 |
1335 | if(r % 4 == 0) // jmp to the original entrypoint
1336 | addr = elfHDR->e_entry;
1337 | else if(r % 4 == 1){ // jmp to _init (".init".sh_addr)
1338 | Elf_Section init;
1339 |
1340 | if(!(init = findSectionIndexByName(".init")))
1341 | return 0;
1342 |
1343 | addr = elfSHT[init].sh_addr;
1344 | } else if(r % 4 == 2){ // jmp to _fini (".fini".sh_addr)
1345 | Elf_Section fini;
1346 |
1347 | if(!(fini = findSectionIndexByName(".fini")))
1348 | return 0;
1349 |
1350 | addr = elfSHT[fini].sh_addr;
1351 | } else
1352 | addr = getElf_Addr();
1353 |
1354 | memcpy(orcptr + elfSHT[sh].sh_offset, &addr, sizeof(addr));
1355 |
1356 | fprintf(logfp, "(SHT[%d]->(sh_offset + 0) = 0x"HEX")", sh, addr);
1357 |
1358 | return 1;
1359 | }
1360 |
1361 | int sht36(void)
1362 | {
1363 | // Metadata dependencies
1364 | switch(orcSHT->sh_type){
1365 | case SHT_STRTAB:
1366 | if(mode & STRS)
1367 | if(rand() % 2) // 50% chance
1368 | return 0;
1369 | break;
1370 | case SHT_NOTE:
1371 | if(mode & NOTE)
1372 | if(rand() % 2)
1373 | return 0;
1374 | break;
1375 | case SHT_DYNAMIC:
1376 | if(mode & DYN)
1377 | if(rand() % 4 < 3)
1378 | return 0;
1379 | break;
1380 | case SHT_SYMTAB:
1381 | case SHT_DYNSYM:
1382 | if(mode & SYM)
1383 | if(rand() % 4 < 3)
1384 | return 0;
1385 | break;
1386 | case SHT_RELA:
1387 | case SHT_REL:
1388 | if(mode & REL)
1389 | if(rand() % 4 < 3)
1390 | return 0;
1391 | break;
1392 | default:
1393 | if(rand() % 3 < 2)
1394 | return 0;
1395 | }
1396 |
1397 | orcSHT->sh_size++;
1398 | orcSHT->sh_entsize--;
1399 |
1400 | fprintf(logfp, "(SHT[%d]->sh_size = 0x"HEX",", sh, orcSHT->sh_size);
1401 | fprintf(logfp, " sh_entsize = 0x"HEX")", orcSHT->sh_entsize);
1402 |
1403 | return 1;
1404 | }
1405 |
1406 | int sht37(void)
1407 | {
1408 | if(sh == 0) // Avoid the first entry of the SHT
1409 | return 0;
1410 |
1411 | Elf_Section tbss = findSectionIndexByName(".tbss");
1412 | Elf_Section tdata = findSectionIndexByName(".tdata");
1413 |
1414 | if(!tbss && !tdata)
1415 | return 0;
1416 |
1417 | if(tbss != sh && tdata != sh)
1418 | return 0;
1419 |
1420 | int fuzzed = 0;
1421 |
1422 | if(tbss){
1423 | orcOrigSHT[tbss].sh_flags &= ~SHF_TLS;
1424 | fuzzed++;
1425 | }
1426 |
1427 | if(tdata){
1428 | orcOrigSHT[tdata].sh_flags &= ~SHF_TLS;
1429 | fuzzed++;
1430 | }
1431 |
1432 | if(!fuzzed)
1433 | return 0;
1434 |
1435 | if(tbss && tdata){
1436 | fprintf(logfp, "(SHT[%d]->sh_flags = 0x"HEX",", tdata, orcOrigSHT[tdata].sh_flags);
1437 | fprintf(logfp, " SHT[%d]->sh_flags = 0x"HEX")", tbss, orcOrigSHT[tbss].sh_flags);
1438 | } else if(tbss)
1439 | fprintf(logfp, "(SHT[%d]->sh_flags = 0x"HEX")", tbss, orcOrigSHT[tbss].sh_flags);
1440 | else
1441 | fprintf(logfp, "(SHT[%d]->sh_flags = 0x"HEX")", tdata, orcOrigSHT[tdata].sh_flags);
1442 |
1443 | return 1;
1444 | }
1445 |
1446 |
1447 | // Will trust only in the original (unmodified) ELF data.
1448 | // Previous rules might already fuzzed sh_name and could SIGSEGV here is orc sh_name is used
1449 | Elf_Section findSectionIndexByName(char *name)
1450 | {
1451 | int k;
1452 | Elf_Shdr *tmpSHT = elfSHT;
1453 |
1454 | for(k = 0; k < elfHDR->e_shnum; k++, tmpSHT++)
1455 | if(strcmp(elfptr + elfshstrtab_offset + tmpSHT->sh_name, name) == 0)
1456 | return k;
1457 |
1458 | return SHT_NULL; // Zero
1459 | }
1460 |
1461 | void fuzzName()
1462 | {
1463 | if(rand() % 3 == 0){
1464 | if(rand() % 2)
1465 | orcSHT->sh_name = getElf_Word();
1466 | else
1467 | orcSHT->sh_name = getElf_Half();
1468 | } else {
1469 | if(rand() % 3 == 0)
1470 | orcSHT->sh_name = 0x00;
1471 | else
1472 | orcSHT->sh_name = (rand() % 0xff);
1473 | }
1474 | }
1475 |
1476 | void fuzzSize()
1477 | {
1478 | if((rand() % 4) < 3){ // 75% chance
1479 | if(rand() % 2)
1480 | #if defined(__i386__) || defined(__ANDROID_API__)
1481 | orcSHT->sh_size = getElf_Word();
1482 | #elif defined(__x86_64__)
1483 | orcSHT->sh_size = getElf_Xword();
1484 | #endif
1485 | else
1486 | orcSHT->sh_size = getElf_Half();
1487 | } else
1488 | orcSHT->sh_size = 0x00;
1489 | }
1490 |
1491 | void fuzzEntSize()
1492 | {
1493 | if((rand() % 4) < 3){ // 75% chance
1494 | if(rand() % 2)
1495 | #if defined(__i386__) || defined(__ANDROID_API__)
1496 | orcSHT->sh_entsize = getElf_Word();
1497 | #elif defined(__x86_64__)
1498 | orcSHT->sh_entsize = getElf_Xword();
1499 | else
1500 | orcSHT->sh_entsize = getElf_Half();
1501 | #endif
1502 | } else
1503 | orcSHT->sh_entsize = 0x00;
1504 | }
1505 |
1506 | void fuzzFlags()
1507 | {
1508 | int r = rand();
1509 |
1510 | if(r % 3 == 0){
1511 | r = rand();
1512 |
1513 | // Set SHF_x
1514 | if(r % 5 == 0)
1515 | orcSHT->sh_flags = (SHF_WRITE | SHF_ALLOC | SHF_EXECINSTR | SHF_TLS | SHF_MASKPROC);
1516 | else if(r % 5 == 1)
1517 | orcSHT->sh_flags |= SHF_WRITE;
1518 | else if(r % 5 == 2)
1519 | orcSHT->sh_flags |= SHF_ALLOC;
1520 | else if(r % 5 == 3)
1521 | orcSHT->sh_flags |= SHF_TLS;
1522 | else
1523 | orcSHT->sh_flags |= SHF_EXECINSTR;
1524 | } else if(r % 3 == 1){
1525 | r = rand();
1526 |
1527 | // Unset SHF_x
1528 | if(r % 5 == 0)
1529 | orcSHT->sh_flags = 0x00;
1530 | else if(r % 5 == 1)
1531 | orcSHT->sh_flags &= ~SHF_WRITE;
1532 | else if(r % 5 == 2)
1533 | orcSHT->sh_flags &= ~SHF_ALLOC;
1534 | else if(r % 5 == 3)
1535 | orcSHT->sh_flags &= ~SHF_TLS;
1536 | else
1537 | orcSHT->sh_flags &= ~SHF_EXECINSTR;
1538 | } else {
1539 | #if defined(__i386__) || defined(__ANDROID_API__)
1540 | orcSHT->sh_flags = getElf_Word();
1541 | #elif defined(__x86_64__)
1542 | orcSHT->sh_flags = getElf_Xword();
1543 | #endif
1544 | }
1545 | }
1546 |
1547 | void fuzzAddrAlign()
1548 | {
1549 | if(rand() % 2){ // 50% chance
1550 | #if defined(__i386__) || defined(__ANDROID_API__)
1551 | while((orcSHT->sh_addralign = getElf_Word()))
1552 | #elif defined(__x86_64__)
1553 | while((orcSHT->sh_addralign = getElf_Xword()))
1554 | #endif
1555 | // Bitwise: x & (x - 1) != 0 if x is NOT a power of 2
1556 | if((orcSHT->sh_addralign & (orcSHT->sh_addralign - 1)) != 0)
1557 | break;
1558 | } else {
1559 | if(rand() % 2) // 25%
1560 | orcSHT->sh_addralign = PAGESIZE - 1;
1561 | else // 25%
1562 | orcSHT->sh_addralign = PAGESIZE + 1;
1563 | }
1564 | }
1565 |
1566 | void initialize_sht_funcs(void)
1567 | {
1568 | sht[1] = &sht1;
1569 | sht[2] = &sht2;
1570 | sht[3] = &sht3;
1571 | sht[4] = &sht4;
1572 | sht[5] = &sht5;
1573 | sht[6] = &sht6;
1574 | sht[7] = &sht7;
1575 | sht[8] = &sht8;
1576 | sht[9] = &sht9;
1577 | sht[10] = &sht10;
1578 | sht[11] = &sht11;
1579 | sht[12] = &sht12;
1580 | sht[13] = &sht13;
1581 | sht[14] = &sht14;
1582 | sht[15] = &sht15;
1583 | sht[16] = &sht16;
1584 | sht[17] = &sht17;
1585 | sht[18] = &sht18;
1586 | sht[19] = &sht19;
1587 | sht[20] = &sht20;
1588 | sht[21] = &sht21;
1589 | sht[22] = &sht22;
1590 | sht[23] = &sht23;
1591 | sht[24] = &sht24;
1592 | sht[25] = &sht25;
1593 | sht[26] = &sht26;
1594 | sht[27] = &sht27;
1595 | sht[28] = &sht28;
1596 | sht[29] = &sht29;
1597 | sht[30] = &sht30;
1598 | sht[31] = &sht31;
1599 | sht[32] = &sht32;
1600 | sht[33] = &sht33;
1601 | sht[34] = &sht34;
1602 | sht[35] = &sht35;
1603 | sht[36] = &sht36;
1604 | sht[37] = &sht37;
1605 | }
1606 |
--------------------------------------------------------------------------------
/jni/src/fuzz_strs.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Melkor - An ELF File Format Fuzzer
3 | * Copyright (C) 2014 Alejandro Hernandez H. (nitr0us)
4 | *
5 | * Mexico
6 | */
7 |
8 | #include "melkor.h"
9 |
10 | #define N_RULES_STRS 3 // Total of fuzzing rules defined for this metadata type
11 |
12 | // Array of function pointers. Index zero won't be used. The fuzzing rules start from index 1
13 | func_ptr strs[N_RULES_STRS + 1];
14 |
15 | void initialize_strs_funcs(void) __attribute__((constructor));
16 |
17 | /* External vars */
18 | extern FILE *logfp;
19 | extern unsigned int mode; // Metadata to fuzz (parameters given in argv[])
20 | extern unsigned int quiet;
21 | extern unsigned int like_a, like_b;
22 | extern unsigned int secnum;
23 | extern char *orcSTRS;
24 | extern Elf_Shdr *orcSHT;
25 |
26 | void fuzz_strs()
27 | {
28 | int rule;
29 |
30 | for(rule = 1; rule <= N_RULES_STRS; rule++)
31 | if((rand() % like_a) < like_b)
32 | if(strs[rule]()){
33 | printf(". ");
34 | debug("STRS[%d] rule [%.2d] executed\n", secnum, rule);
35 | fprintf(logfp, " | STRS[%d] rule [%.2d] executed\n", secnum, rule);
36 | }
37 | }
38 |
39 | int strs1(void)
40 | {
41 | if(mode & (SHT | NOTE | DYN | SYM | REL))
42 | if(rand() % 3 < 2)
43 | return 0;
44 |
45 | unsigned int ptr_offset = (rand() % 15) + 1; // Avoid the first NULL byte (index 0)
46 |
47 | fprintf(logfp, "(STRS[%d]->sh_offset (0x%x) + ", secnum, (unsigned int) orcSHT->sh_offset);
48 |
49 | while(ptr_offset < orcSHT->sh_size - 1){
50 | if(*(orcSTRS + ptr_offset) == 0){
51 | ptr_offset += rand() % 15 + rand() % 15;
52 | continue;
53 | }
54 |
55 | *(orcSTRS + ptr_offset) = (rand() & 0x7f) + 0x80; // > 7-bit ASCII chars
56 | fprintf(logfp, "%d = %c (0x%.2x), ", ptr_offset, *(orcSTRS + ptr_offset), *(orcSTRS + ptr_offset) & 0xff);
57 |
58 | ptr_offset += rand() % 15 + rand() % 15;
59 | }
60 |
61 | fprintf(logfp, ")");
62 |
63 | return 1;
64 | }
65 |
66 | int strs2(void)
67 | {
68 | if(mode & (SHT | NOTE | DYN | SYM | REL))
69 | if(rand() % 3 < 2)
70 | return 0;
71 |
72 | fprintf(logfp, "(STRS[%d]->sh_offset (0x%x) + ", secnum, (unsigned int) orcSHT->sh_offset);
73 |
74 | if(rand() % 2){
75 | unsigned int ptr_offset = 1;
76 |
77 | while(ptr_offset < orcSHT->sh_size - 1){
78 | if(*(orcSTRS + ptr_offset) != 0){
79 | ptr_offset += rand() % 5;
80 | continue;
81 | }
82 |
83 | *(orcSTRS + ptr_offset) = (rand() & 0x7f) + 0x80; // > 7-bit ASCII chars
84 | fprintf(logfp, "%d = %c (0x%.2x), ", ptr_offset, *(orcSTRS + ptr_offset), *(orcSTRS + ptr_offset) & 0xff);
85 |
86 | ptr_offset += rand() % 5;
87 | }
88 | } else {
89 | *(orcSTRS) = (rand() & 0x7f) + 0x80; // > 7-bit ASCII chars
90 | fprintf(logfp, "0 = %c (0x%.2x), ", *(orcSTRS), *(orcSTRS) & 0xff);
91 |
92 | *(orcSTRS + orcSHT->sh_size - 1) = (rand() & 0x7f) + 0x80;
93 | fprintf(logfp, "%d = %c (0x%.2x), ", (int) orcSHT->sh_size - 1, *(orcSTRS + orcSHT->sh_size - 1), *(orcSTRS + orcSHT->sh_size - 1) & 0xff);
94 | }
95 |
96 | fprintf(logfp, ")");
97 |
98 | return 1;
99 | }
100 |
101 | int strs3(void)
102 | {
103 | if(mode & (SHT | NOTE | DYN | SYM | REL))
104 | if(rand() % 3 < 2)
105 | return 0;
106 |
107 | unsigned int ptr_offset = rand() % 20;
108 | char *fmt_ptr;
109 |
110 | fprintf(logfp, "(STRS[%d]->sh_offset (0x%x) + ", secnum, (unsigned int) orcSHT->sh_offset);
111 |
112 | while(ptr_offset < orcSHT->sh_size - 2){
113 | fmt_ptr = get_fmt_str();
114 |
115 | memcpy(orcSTRS + ptr_offset, fmt_ptr, strlen(fmt_ptr));
116 | fprintf(logfp, "%d =%s, ", ptr_offset, fmt_ptr);
117 |
118 | ptr_offset += rand() % 20 + rand() % 20;
119 | }
120 |
121 | fprintf(logfp, ")");
122 |
123 | return 1;
124 | }
125 |
126 | void initialize_strs_funcs(void)
127 | {
128 | strs[1] = &strs1;
129 | strs[2] = &strs2;
130 | strs[3] = &strs3;
131 | }
132 |
--------------------------------------------------------------------------------
/jni/src/fuzz_sym.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Melkor - An ELF File Format Fuzzer
3 | * Copyright (C) 2014 Alejandro Hernandez H. (nitr0us)
4 | *
5 | * Mexico
6 | */
7 |
8 | #include "melkor.h"
9 |
10 | #define N_RULES_SYM 15 // Total of fuzzing rules defined for this metadata type
11 |
12 | // Array of function pointers. Index zero won't be used. The fuzzing rules start from index 1
13 | func_ptr sym[N_RULES_SYM + 1];
14 |
15 | void initialize_sym_funcs(void) __attribute__((constructor));
16 |
17 | /* External vars */
18 | extern FILE *logfp;
19 | extern unsigned int mode; // Metadata to fuzz (parameters given in argv[])
20 | extern unsigned int quiet;
21 | extern unsigned int like_a, like_b;
22 | extern unsigned int secnum;
23 | extern unsigned int entry;
24 | extern Elf_Ehdr *orcHDR;
25 | extern Elf_Sym *orcSYM;
26 |
27 | void fuzz_sym()
28 | {
29 | int rule;
30 |
31 | for(rule = 1; rule <= N_RULES_SYM; rule++)
32 | if((rand() % like_a) < like_b)
33 | if(sym[rule]()){
34 | printf(". ");
35 | debug("SHT[%d] SYM[%d] rule [%.2d] executed\n", secnum, entry, rule);
36 | fprintf(logfp, " | SHT[%d] SYM[%d] rule [%.2d] executed\n", secnum, entry, rule);
37 | }
38 | }
39 |
40 | int sym1(void)
41 | {
42 | if(entry != STN_UNDEF)
43 | return 0;
44 |
45 | if(rand() % 2)
46 | return 0;
47 |
48 | #if defined(__i386__) || defined(__ANDROID_API__)
49 | orcSYM->st_size = getElf_Word();
50 | #elif defined(__x86_64__)
51 | if(rand() % 3 < 2)
52 | orcSYM->st_size = getElf_Xword();
53 | else
54 | orcSYM->st_size = getElf_Word();
55 | #endif
56 |
57 | orcSYM->st_value = getElf_Addr();
58 | orcSYM->st_info = rand() & 0xff;
59 | orcSYM->st_other = rand() & 0xff;
60 |
61 | if(rand() % 4 == 0)
62 | orcSYM->st_shndx = getElf_Section();
63 | else
64 | orcSYM->st_shndx = rand() % orcHDR->e_shnum;
65 |
66 | if(rand() % 4 == 0)
67 | orcSYM->st_name = getElf_Word();
68 | else
69 | orcSYM->st_name = rand() & 0xff;
70 |
71 | fprintf(logfp, "(SYM[%d]->st_value = 0x"HEX",", entry, orcSYM->st_value);
72 | fprintf(logfp, " st_size = 0x"HEX",", orcSYM->st_size);
73 | fprintf(logfp, " st_info = 0x%x,", orcSYM->st_info);
74 | fprintf(logfp, " st_other = 0x%x,", orcSYM->st_other);
75 | fprintf(logfp, " st_shndx = 0x%x,", orcSYM->st_shndx);
76 | fprintf(logfp, " st_name = 0x%x)", orcSYM->st_name);
77 |
78 | return 1;
79 | }
80 |
81 | int sym2(void)
82 | {
83 | if(rand() % 5 < 4) // 80% chance to return. The symbol name is important.
84 | return 0;
85 |
86 | if(mode & REL)
87 | if(rand() % 2)
88 | return 0;
89 |
90 | if(rand() % 4 == 0)
91 | orcSYM->st_name = getElf_Word();
92 | else
93 | orcSYM->st_name = rand() & 0xff;
94 |
95 | fprintf(logfp, "(SYM[%d]->st_name = 0x%x)", entry, orcSYM->st_name);
96 |
97 | return 1;
98 | }
99 |
100 | int sym3(void)
101 | {
102 | if(rand() % 5 < 4) // 80% chance to return. st_value is fuzzed in other rules as well.
103 | return 0;
104 |
105 | if(rand() % 4 < 3)
106 | orcSYM->st_value = getElf_Addr();
107 | else
108 | orcSYM->st_value = getElf_Word();
109 |
110 | fprintf(logfp, "(SYM[%d]->st_value = 0x"HEX")", entry, orcSYM->st_value);
111 |
112 | return 1;
113 | }
114 |
115 | int sym4(void)
116 | {
117 | #if defined(__i386__) || defined(__ANDROID_API__)
118 | orcSYM->st_size = getElf_Word();
119 | #elif defined(__x86_64__)
120 | if(rand() % 3 < 2)
121 | orcSYM->st_size = getElf_Xword();
122 | else
123 | orcSYM->st_size = getElf_Word();
124 | #endif
125 |
126 | fprintf(logfp, "(SYM[%d]->st_size = 0x"HEX")", entry, orcSYM->st_size);
127 |
128 | return 1;
129 | }
130 |
131 | int sym5(void)
132 | {
133 | if(rand() % 2)
134 | return 0;
135 |
136 | if(mode & REL)
137 | if(rand() % 2)
138 | return 0;
139 |
140 | if(rand() % 2)
141 | orcSYM->st_shndx = rand() % orcHDR->e_shnum;
142 | else {
143 | if(rand() % 2)
144 | orcSYM->st_shndx = getElf_Section();
145 | else
146 | orcSYM->st_shndx = SHN_UNDEF;
147 | }
148 |
149 | fprintf(logfp, "(SYM[%d]->st_shndx = 0x%x)", entry, orcSYM->st_shndx);
150 |
151 | return 1;
152 | }
153 |
154 | int sym6(void)
155 | {
156 | if(ELF_ST_TYPE(orcSYM->st_info) != STT_SECTION)
157 | return 0;
158 |
159 | if(mode & REL)
160 | if(rand() % 2)
161 | return 0;
162 |
163 | unsigned char st_info;
164 |
165 | do
166 | st_info = ELF_ST_INFO(rand() & 0x0f, STT_SECTION);
167 | while(ELF_ST_BIND(st_info) == STB_LOCAL);
168 |
169 | orcSYM->st_info = st_info;
170 |
171 | fprintf(logfp, "(SYM[%d]->st_info = 0x%.2x)", entry, orcSYM->st_info);
172 |
173 | return 1;
174 | }
175 |
176 | int sym7(void)
177 | {
178 | if(ELF_ST_TYPE(orcSYM->st_info) != STT_FILE)
179 | return 0;
180 |
181 | if(mode & REL)
182 | if(rand() % 2)
183 | return 0;
184 |
185 | unsigned char st_info = orcSYM->st_info;
186 | Elf_Section st_shndx;
187 |
188 | if(rand() % 2)
189 | do
190 | st_info = ELF_ST_INFO(rand() & 0x0f, STT_FILE);
191 | while(ELF_ST_BIND(st_info) == STB_LOCAL);
192 |
193 | if(rand() % 4 < 3){
194 | while((st_shndx = rand() % orcHDR->e_shnum))
195 | if(st_shndx != SHN_ABS)
196 | break;
197 | } else
198 | while((st_shndx = getElf_Section()))
199 | if(st_shndx != SHN_ABS)
200 | break;
201 |
202 | orcSYM->st_info = st_info;
203 | orcSYM->st_shndx = st_shndx;
204 |
205 | fprintf(logfp, "(SYM[%d]->st_info = 0x%.2x,", entry, orcSYM->st_info);
206 | fprintf(logfp, " st_shndx = 0x%x)", orcSYM->st_shndx);
207 |
208 | return 1;
209 | }
210 |
211 | int sym8(void)
212 | {
213 | if(orcHDR->e_type != ET_REL ||
214 | orcSYM->st_shndx != SHN_COMMON)
215 | return 0;
216 |
217 | Elf_Addr st_value;
218 |
219 | while((st_value = getElf_Addr()))
220 | if(st_value % 4 != 0)
221 | break;
222 |
223 | orcSYM->st_value = st_value;
224 |
225 | fprintf(logfp, "(SYM[%d]->st_value = 0x"HEX")", entry, orcSYM->st_value);
226 |
227 | return 1;
228 | }
229 |
230 | int sym9(void)
231 | {
232 | if(orcHDR->e_type != ET_REL ||
233 | orcSYM->st_shndx == SHN_COMMON)
234 | return 0;
235 |
236 | if(rand() % 2)
237 | orcSYM->st_value = getElf_Off();
238 | else
239 | orcSYM->st_value = getElf_Word();
240 |
241 | fprintf(logfp, "(SYM[%d]->st_value = 0x"HEX")", entry, orcSYM->st_value);
242 |
243 | return 1;
244 | }
245 |
246 | int sym10(void)
247 | {
248 | if(orcHDR->e_type != ET_EXEC &&
249 | orcHDR->e_type != ET_DYN)
250 | return 0;
251 |
252 | if(rand() % 5 < 4)
253 | return 0;
254 |
255 | orcSYM->st_value = getElf_Addr();
256 |
257 | fprintf(logfp, "(SYM[%d]->st_value = 0x"HEX")", entry, orcSYM->st_value);
258 |
259 | return 1;
260 | }
261 |
262 | int sym11(void)
263 | {
264 | if(orcHDR->e_type != ET_EXEC &&
265 | orcHDR->e_type != ET_DYN)
266 | return 0;
267 |
268 | if(rand() % 5 < 4)
269 | return 0;
270 |
271 | if(mode & REL)
272 | if(rand() % 2)
273 | return 0;
274 |
275 | if(rand() % 2)
276 | orcSYM->st_shndx = 1 + rand() % orcHDR->e_shnum;
277 | else
278 | orcSYM->st_shndx = (rand() % 10) + getElf_Section();
279 |
280 | fprintf(logfp, "(SYM[%d]->st_shndx = 0x%x)", entry, orcSYM->st_shndx);
281 |
282 | return 1;
283 | }
284 |
285 | int sym12(void)
286 | {
287 | if(orcSYM->st_shndx != SHN_UNDEF)
288 | return 0;
289 |
290 | if(!orcSYM->st_value)
291 | return 0;
292 |
293 | orcSYM->st_value = getElf_Addr();
294 |
295 | fprintf(logfp, "(SYM[%d]->st_value = 0x"HEX")", entry, orcSYM->st_value);
296 |
297 | return 1;
298 | }
299 |
300 | int sym13(void)
301 | {
302 | if(rand() % 4 < 3)
303 | return 0;
304 |
305 | if(mode & REL)
306 | if(rand() % 2)
307 | return 0;
308 |
309 | orcSYM->st_info = rand() & 0xff;
310 |
311 | fprintf(logfp, "(SYM[%d]->st_info = 0x%.2x)", entry, orcSYM->st_info);
312 |
313 | return 1;
314 | }
315 |
316 | int sym14(void)
317 | {
318 | if(rand() % 4 < 3)
319 | return 0;
320 |
321 | if(mode & REL)
322 | if(rand() % 2)
323 | return 0;
324 |
325 | orcSYM->st_info = ELF_ST_INFO(rand() % 2 ? STB_LOOS : STB_HIOS, rand() % 2 ? STT_LOOS : STT_HIOS);
326 |
327 | fprintf(logfp, "(SYM[%d]->st_info = 0x%.2x)", entry, orcSYM->st_info);
328 |
329 | return 1;
330 | }
331 |
332 | int sym15(void)
333 | {
334 | orcSYM->st_other = rand() & 0xff;
335 |
336 | fprintf(logfp, "(SYM[%d]->st_other = 0x%.2x)", entry, orcSYM->st_other);
337 |
338 | return 1;
339 | }
340 |
341 | void initialize_sym_funcs(void)
342 | {
343 | sym[1] = &sym1;
344 | sym[2] = &sym2;
345 | sym[3] = &sym3;
346 | sym[4] = &sym4;
347 | sym[5] = &sym5;
348 | sym[6] = &sym6;
349 | sym[7] = &sym7;
350 | sym[8] = &sym8;
351 | sym[9] = &sym9;
352 | sym[10] = &sym10;
353 | sym[11] = &sym11;
354 | sym[12] = &sym12;
355 | sym[13] = &sym13;
356 | sym[14] = &sym14;
357 | sym[15] = &sym15;
358 | }
359 |
--------------------------------------------------------------------------------
/jni/src/generators.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Melkor - An ELF File Format Fuzzer
3 | * Copyright (C) 2014 Alejandro Hernandez H. (nitr0us)
4 | *
5 | * Mexico
6 | */
7 |
8 | #include "melkor.h"
9 | #include "numbers.h"
10 |
11 | #include
12 | #include
13 |
14 | unsigned int getseed(void)
15 | {
16 | int fd;
17 | unsigned int seed;
18 |
19 | if((fd = open("/dev/urandom", O_RDONLY)) == -1){
20 | perror("getseed(): open");
21 | exit(EXIT_FAILURE);
22 | }
23 |
24 | read(fd, &seed, sizeof(seed));
25 |
26 | close(fd);
27 |
28 | return seed;
29 | }
30 |
31 | Elf_Addr getElf_Addr(void)
32 | {
33 | Elf_Addr a;
34 |
35 | if(rand() % 2)
36 | // A key base address + 16 bits random offset
37 | a = (Elf_Addr) (key_Addr[rand() % (sizeof(key_Addr) / sizeof(Elf_Addr))] + (rand() & 0xffff));
38 | else {
39 | if(rand() % 2){
40 | int r = rand();
41 |
42 | if(r % 3 == 0)
43 | a = (Elf_Addr) int_l33t[rand() % (sizeof(int_l33t) / sizeof(int))];
44 | else if(r % 3 == 1)
45 | a = (Elf_Addr) int_b0f[rand() % (sizeof(int_b0f) / sizeof(int))];
46 | else
47 | a = (Elf_Addr) common_b0f[rand() % (sizeof(common_b0f) / sizeof(int))];
48 | } else
49 | a = (Elf_Addr) rand();
50 | }
51 |
52 | return a;
53 | }
54 |
55 | Elf_Off getElf_Off(void)
56 | {
57 | Elf_Off o;
58 | int r = rand();
59 |
60 | if(r % 5 == 0) // 20% chance
61 | o = (Elf_Off) (key_Addr[rand() % (sizeof(key_Addr) / sizeof(Elf_Addr))] + (rand() % 0xffff));
62 | else if(r % 5 == 1)
63 | o = (Elf_Off) int_l33t[rand() % (sizeof(int_l33t) / sizeof(int))];
64 | else if(r % 5 == 2)
65 | o = (Elf_Off) int_b0f[rand() % (sizeof(int_b0f) / sizeof(int))];
66 | else if(r % 5 == 3)
67 | o = (Elf_Off) common_b0f[rand() % (sizeof(common_b0f) / sizeof(int))];
68 | else
69 | o = (Elf_Off) rand();
70 |
71 | return o;
72 | }
73 |
74 | Elf_Word getElf_Word(void)
75 | {
76 | Elf_Word w;
77 | int r = rand();
78 |
79 | if(r % 3 == 0) // 33.33% chance
80 | w = (Elf_Word) int_l33t[rand() % (sizeof(int_l33t) / sizeof(int))];
81 | else if(r % 3 == 1){
82 | if(rand() % 2)
83 | w = (Elf_Word) int_b0f[rand() % (sizeof(int_b0f) / sizeof(int))];
84 | else
85 | w = (Elf_Word) common_b0f[rand() % (sizeof(common_b0f) / sizeof(int))];
86 | } else
87 | w = (Elf_Word) rand();
88 |
89 | return w;
90 | }
91 |
92 | Elf_Xword getElf_Xword(void)
93 | {
94 | Elf_Xword xw;
95 |
96 | xw = getElf_Word();
97 | xw = xw << 32 | getElf_Word();
98 |
99 | return xw;
100 | }
101 |
102 | Elf_Half getElf_Half(void)
103 | {
104 | Elf_Half h;
105 | int r = rand();
106 |
107 | if(r % 5 == 0) // 20% chance
108 | h = (Elf_Half) short_l33t[rand() % (sizeof(short_l33t) / sizeof(int))];
109 | else if(r % 5 == 1)
110 | h = (Elf_Half) (int_b0f[rand() % 3] >> 16); // 0x7fff || 0xffff || 0x8000
111 | else if(r % 5 == 2)
112 | h = (Elf_Half) (int_b0f[(rand() % (sizeof(int_b0f) / sizeof(int))) + 3] >> 16);
113 | else if(r % 5 == 3)
114 | h = (Elf_Half) common_b0f[rand() % (sizeof(common_b0f) / sizeof(int))] >> 16;
115 | else
116 | h = (Elf_Half) rand();
117 |
118 | return h;
119 | }
120 |
121 | Elf_Section getElf_Section(void)
122 | {
123 | Elf_Section s;
124 |
125 | if(rand() % 2) // 50% chance to return a small (valid?) value
126 | s = (Elf_Section) rand() % 0x20;
127 | else
128 | s = (Elf_Section) getElf_Half();
129 |
130 | return s;
131 | }
132 |
133 | char *get_fmt_str(void)
134 | {
135 | char *fmt_ptr;
136 |
137 | fmt_ptr = (char *) fmt_strs[rand() % (sizeof(fmt_strs) / sizeof(char *))];
138 |
139 | return fmt_ptr;
140 | }
141 |
142 | char *get_fuzzed_path(void)
143 | {
144 | char *fuzzed_path;
145 |
146 | fuzzed_path = (char *) fuzz_paths[rand() % (sizeof(fuzz_paths) / sizeof(char *))];
147 |
148 | return fuzzed_path;
149 | }
150 |
--------------------------------------------------------------------------------
/jni/src/logger.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Melkor - An ELF File Format Fuzzer
3 | * Copyright (C) 2014 Alejandro Hernandez H. (nitr0us)
4 | *
5 | * Mexico
6 | */
7 |
8 | #include "melkor.h"
9 |
10 | FILE *start_logger(char *logfname, char *elfname)
11 | {
12 | FILE *fp;
13 | const char *log_line = " ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~\n";
14 |
15 | char log_title[strlen(logfname) + 100];
16 | snprintf(log_title, sizeof(log_title), "| Log report for fuzzed files based on %-25s |\n", elfname);
17 |
18 | if(!(fp = fopen(logfname, "w"))){
19 | perror("fopen");
20 | exit(EXIT_FAILURE);
21 | }
22 |
23 | fputs(log_line, fp);
24 | fputs(log_title, fp);
25 | fputs(log_line, fp);
26 | fputs("\nHow to read this report:\n\n", fp);
27 | fputs("(Fuzzed Metadata) | Corresponding fuzzing rule (docs/Melkor_Fuzzing_Rules.pdf)\n\n", fp);
28 | fputs("SHT[N] REL[E] = Section Header N type is SHT_REL or SHT_RELA; Relocation entry E within that section was fuzzed.\n", fp);
29 | fputs("SHT[N] SYM[E] = Section Header N type is SHT_SYMTAB or SHT_DYNSYM; Symbol entry E within that section was fuzzed.\n", fp);
30 | fputs("SHT[N] DYN[E] = Section Header N type is SHT_DYNAMIC; Dynamic entry E within that section was fuzzed.\n", fp);
31 | fputs("SHT[N] NOTE[E] = Section Header N type is SHT_NOTE; Note entry E within that section was fuzzed.\n", fp);
32 | fputs("STRS[N] = Section Header N type is SHT_STRTAB; the String Table within that section was fuzzed.\n", fp);
33 | fputs("SHT[N] = Section Header N was fuzzed.\n", fp);
34 | fputs("PHT[N] = Program Header N was fuzzed.\n", fp);
35 | fputs("HDR = ELF Header was fuzzed.\n", fp);
36 |
37 | return fp;
38 | }
39 |
40 | void stop_logger(FILE *fp)
41 | {
42 | const char *log_footer =
43 | "\n\n ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~\n"
44 | "| End of report. |\n"
45 | " ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~\n";
46 |
47 | fputs(log_footer, fp);
48 |
49 | fclose(fp);
50 | }
51 |
--------------------------------------------------------------------------------
/jni/src/melkor.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Melkor - An ELF File Format Fuzzer
3 | * Copyright (C) 2014 Alejandro Hernandez H. (nitr0us)
4 | *
5 | * This program is free software: you can redistribute it and/or modify
6 | * it under the terms of the GNU General Public License as published by
7 | * the Free Software Foundation, either version 3 of the License, or
8 | * (at your option) any later version.
9 | *
10 | * This program is distributed in the hope that it will be useful,
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | * GNU General Public License for more details.
14 | *
15 | * You should have received a copy of the GNU General Public License
16 | * along with this program. If not, see .
17 | *
18 | * Mexico
19 | */
20 |
21 | #include "melkor.h"
22 | #include "banner.h"
23 |
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 |
31 | /* GLOBAL VARS */
32 | FILE *logfp;
33 | struct stat elfstatinfo;
34 | unsigned int mode = 0; // Metadata to fuzz (parameters)
35 | unsigned int orcn = 0; // OrcN inside the for() loop. fuzz_* modules will use it through different loops
36 | unsigned int n = 5000; // Default for option -n
37 | unsigned int quiet = 0; // For quiet mode (-q). Default is not quiet [debug() output]
38 | unsigned int likelihood = 10; // Likelihood given in % of the execution of each rule in the main for() loop in fuzz_*.c. Default 10%
39 | unsigned int like_a = 10, like_b = 1; // Based upon the likelihood, these will be used for: rand() % like_a < like_b. Default values for 10%
40 | unsigned int secnum = 0; // Used in loops here but refered in fuzz_*.c as the section number
41 | unsigned int entry = 0; // Used in loops here but refered in fuzz_*.c as the entry number inside a section (for DYN, SYM, REL)
42 | char *dirname_orcfname;
43 | char *elfptr, *orcptr;
44 | char *elfSTRS, *orcSTRS;
45 | Elf_Ehdr *elfHDR, *orcHDR;
46 | Elf_Shdr *elfSHT, *orcSHT;
47 | Elf_Phdr *elfPHT, *orcPHT;
48 | Elf_Sym *elfSYM, *orcSYM;
49 | Elf_Dyn *elfDYN, *orcDYN;
50 | Elf_Rel *elfREL, *orcREL;
51 | Elf_Rela *elfRELA, *orcRELA;
52 | Elf_Nhdr *elfNOTE, *orcNOTE;
53 | Elf_Off elfshstrtab_offset = 0, orcshstrtab_offset = 0, linkstrtab_offset = 0;
54 | Elf_Shdr *orcOrigSHT;
55 | Elf_Phdr *orcOrigPHT;
56 | Elf_Dyn *elfOrigDYN;
57 |
58 | int main(int argc, char **argv)
59 | {
60 | int opt, elffd, orcfd, fuzzed_flag = 0, k = 0;
61 | char *elfname;
62 | Elf_Shdr elfshstrtab_section, orcshstrtab_section, linkstrtab_section;
63 |
64 | if(argc < 3)
65 | usage(argv[0]);
66 |
67 | while((opt = getopt(argc, argv, "aHSPsDRNZABqn:l:")) != EOF)
68 | switch(opt){
69 | case 'a':
70 | mode |= AUTO;
71 | break;
72 | case 'H':
73 | mode |= HDR;
74 | break;
75 | case 'S':
76 | mode |= SHT;
77 | break;
78 | case 'P':
79 | mode |= PHT;
80 | break;
81 | case 's':
82 | mode |= SYM;
83 | break;
84 | case 'D':
85 | mode |= DYN;
86 | break;
87 | case 'R':
88 | mode |= REL;
89 | break;
90 | case 'N':
91 | mode |= NOTE;
92 | break;
93 | case 'Z':
94 | mode |= STRS;
95 | break;
96 | case 'A':
97 | mode |= ALL;
98 | break;
99 | case 'B':
100 | mode |= ALLB;
101 | break;
102 | case 'n':
103 | n = atoi(optarg);
104 | break;
105 | case 'l':
106 | likelihood = atoi(optarg);
107 | if(likelihood < 1 || likelihood > 100){
108 | fprintf(stderr, "[!] Likelihood (-l) is given in %% and must be between 1 and 100\n");
109 | exit(EXIT_FAILURE);
110 | }
111 |
112 | /*
113 | rand() % 20 < 1 = 5%
114 | rand() % 10 < 1 = 10%
115 | rand() % 5 < 1 = 20%
116 | rand() % 4 < 1 = 25%
117 | rand() % 3 < 1 = 33.33%
118 | rand() % 5 < 2 = 40%
119 | rand() % 2 < 1 = 50%
120 | rand() % 5 < 3 = 60%
121 | rand() % 3 < 2 = 66.66%
122 | rand() % 4 < 3 = 75%
123 | rand() % 5 < 4 = 80%
124 | rand() % 10 < 9 = 90%
125 | rand() % 1 < 1 = 100%
126 | */
127 | if(likelihood <= 5){
128 | like_a = 20;
129 | like_b = 1;
130 | } else if(likelihood <= 10){
131 | like_a = 10;
132 | like_b = 1;
133 | } else if(likelihood <= 20){
134 | like_a = 5;
135 | like_b = 1;
136 | } else if(likelihood <= 25){
137 | like_a = 4;
138 | like_b = 1;
139 | } else if(likelihood <= 34){
140 | like_a = 3;
141 | like_b = 1;
142 | } else if(likelihood <= 40){
143 | like_a = 5;
144 | like_b = 2;
145 | } else if(likelihood <= 50){
146 | like_a = 2;
147 | like_b = 1;
148 | } else if(likelihood <= 60){
149 | like_a = 5;
150 | like_b = 3;
151 | } else if(likelihood <= 67){
152 | like_a = 3;
153 | like_b = 2;
154 | } else if(likelihood <= 75){
155 | like_a = 4;
156 | like_b = 3;
157 | } else if(likelihood <= 80){
158 | like_a = 5;
159 | like_b = 4;
160 | } else if(likelihood <= 90){
161 | like_a = 10;
162 | like_b = 9;
163 | } else if(likelihood <= 100){
164 | like_a = 1;
165 | like_b = 1;
166 | }
167 | break;
168 | case 'q':
169 | quiet = 1;
170 | break;
171 | default:
172 | exit(EXIT_FAILURE);
173 | }
174 |
175 | if(argv[optind] == NULL){
176 | fprintf(stderr, "[!] not supplied !\n");
177 | exit(EXIT_FAILURE);
178 | }
179 |
180 | /* Separate the filename from the dirname. The same as basename() */
181 | elfname = strrchr(argv[optind], '/');
182 | if(!elfname)
183 | elfname = argv[optind];
184 | else
185 | elfname = strrchr(argv[optind], '/') + 1;
186 |
187 | if((elffd = open(argv[optind], O_RDONLY)) == -1){
188 | perror("open");
189 | exit(EXIT_FAILURE);
190 | }
191 |
192 | if(!elf_identification(elffd)){
193 | fprintf(stderr, "[!] '%s' is not an ELF file. Invalid magic number !\n", elfname);
194 | close(elffd);
195 | exit(EXIT_FAILURE);
196 | }
197 |
198 | if(fstat(elffd, &elfstatinfo) == -1){
199 | perror("stat");
200 | close(elffd);
201 | exit(EXIT_FAILURE);
202 | }
203 |
204 | if((elfptr = (char *) mmap(NULL, elfstatinfo.st_size, PROT_READ, MAP_SHARED, elffd, 0)) == MAP_FAILED){
205 | perror("mmap");
206 | close(elffd);
207 | exit(EXIT_FAILURE);
208 | }
209 |
210 | close(elffd);
211 |
212 | elfHDR = (Elf_Ehdr *) (elfptr);
213 | elfSHT = (Elf_Shdr *) (elfptr + elfHDR->e_shoff);
214 | elfPHT = (Elf_Phdr *) (elfptr + elfHDR->e_phoff);
215 | elfshstrtab_section = *(Elf_Shdr *) (elfSHT + elfHDR->e_shstrndx);
216 | elfshstrtab_offset = elfshstrtab_section.sh_offset;
217 |
218 | char dirname[strlen("orcs_") + strlen(elfname) + 1];
219 | char orcfname[strlen("orc_") + 16];
220 | char logfname[strlen("Report_") + strlen(elfname) + 5];
221 | char *ext = "";
222 | if(strcmp(elfname + strlen(elfname) - 2, ".o") == 0)
223 | ext = ".o";
224 | if(strcmp(elfname + strlen(elfname) - 3, ".so") == 0)
225 | ext = ".so";
226 |
227 | dirname_orcfname = malloc(sizeof(dirname) + sizeof(orcfname) + 2);
228 |
229 | snprintf(dirname, sizeof(dirname), "orcs_%s", elfname);
230 | snprintf(logfname, sizeof(logfname), "Report_%s.txt", elfname);
231 |
232 | if(mkdir(dirname, 0775) == -1)
233 | if(errno == EEXIST)
234 | printf("[!] Dir '%s' already exists. Files inside will be overwritten !\n", dirname);
235 |
236 | printf("%s", elf_ascii[0]);
237 | printf(elf_ascii[1], argv[optind]);
238 | printf("%s", elf_ascii[2]);
239 | printf(elf_ascii[3], n);
240 | printf("%s", elf_ascii[4]);
241 |
242 | if(mode & AUTO){
243 | printf("[+] Automatic mode\n");
244 | printf("[+] ELF type detected: ");
245 |
246 | switch(elfHDR->e_type){
247 | case ET_NONE:
248 | printf("ET_NONE");
249 | break;
250 | case ET_REL:
251 | printf("ET_REL");
252 | break;
253 | case ET_EXEC:
254 | printf("ET_EXEC");
255 | break;
256 | case ET_DYN:
257 | printf("ET_DYN");
258 | break;
259 | case ET_CORE:
260 | printf("ET_CORE");
261 | break;
262 | default:
263 | printf("Unknown e_type !\n");
264 | printf("[+] All the metadata (except) the header will be fuzzed\n\n");
265 | }
266 |
267 | if(elfHDR->e_type > 0 && elfHDR->e_type < 5){
268 | printf("\n[+] Selecting the metadata to fuzz\n\n");
269 |
270 | int metadata_by_e_type[5][8] = {
271 | /* HDR SHT PHT SYM DYN REL NOTE STRS */
272 | /* ET_NONE */ { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, // Untouched
273 | /* ET_REL */ { 0 , SHT, 0 , SYM, 0 , REL, 0 , STRS },
274 | /* ET_EXEC */ { 0 , SHT, PHT, SYM, DYN, REL, NOTE, STRS },
275 | /* ET_DYN */ { 0 , SHT, PHT, SYM, DYN, REL, NOTE, STRS },
276 | /* ET_CORE */ { 0 , 0 , PHT, 0 , 0 , 0 , 0 , 0 },
277 | };
278 |
279 | for(k = 0; k < 8; k++)
280 | mode |= metadata_by_e_type[elfHDR->e_type][k];
281 | } else {
282 | mode = ALLB; // All except the ELF header
283 | }
284 | }
285 |
286 | printf("[+] Detailed log for this session: '%s/%s' \n\n", dirname, logfname);
287 |
288 | printf("[+] The Likelihood of execution of each rule is: ");
289 | printf("Aprox. %d %% (rand() %% %d < %d)\n\n", likelihood, like_a, like_b);
290 |
291 | printf("[+] Press any key to start the fuzzing process...\n");
292 |
293 | getchar();
294 |
295 | chdir(dirname);
296 |
297 | logfp = start_logger(logfname, elfname);
298 |
299 | srand(getseed());
300 | #ifndef __ANDROID_API__
301 | PAGESIZE = getpagesize();
302 | #endif
303 |
304 | for(orcn = 1; orcn <= n; orcn++){
305 | snprintf(orcfname, sizeof(orcfname), "orc_%.4d%s", orcn, ext);
306 | snprintf(dirname_orcfname, sizeof(dirname) + sizeof(orcfname) + 2, "%s/%s", dirname, orcfname);
307 |
308 | if((orcfd = creat(orcfname, elfstatinfo.st_mode)) == -1){
309 | perror("creat");
310 | continue;
311 | }
312 |
313 | if(write(orcfd, elfptr, elfstatinfo.st_size) == -1){
314 | perror("write");
315 | continue;
316 | }
317 |
318 | close(orcfd);
319 |
320 | if((orcfd = open(orcfname, O_RDWR)) == -1){
321 | perror("open");
322 | continue;
323 | }
324 |
325 | if((orcptr = (char *) mmap(NULL, elfstatinfo.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, orcfd, 0)) == MAP_FAILED){
326 | perror("mmap");
327 | close(orcfd);
328 | continue;
329 | }
330 |
331 | orcHDR = (Elf_Ehdr *) (orcptr);
332 | orcOrigSHT = (Elf_Shdr *) (orcptr + orcHDR->e_shoff);
333 | orcOrigPHT = (Elf_Phdr *) (orcptr + orcHDR->e_phoff);
334 | orcshstrtab_section = *(Elf_Shdr *) (orcOrigSHT + orcHDR->e_shstrndx);
335 | orcshstrtab_offset = orcshstrtab_section.sh_offset;
336 |
337 | printf("\n=================================================================================\n");
338 | printf("[+] Malformed ELF '%s':\n", orcfname);
339 | fprintf(logfp, "\n=================================================================================\n\n");
340 | fprintf(logfp, "[+] Malformed ELF: '%s':\n\n", orcfname);
341 |
342 | if(mode & REL){
343 | verifySHT();
344 | orcSHT = orcOrigSHT;
345 |
346 | fuzzed_flag = 0;
347 | entry = 0;
348 |
349 | for(secnum = 0; secnum < orcHDR->e_shnum; secnum++, orcSHT++){
350 | if(orcSHT->sh_type != SHT_REL && orcSHT->sh_type != SHT_RELA)
351 | continue;
352 |
353 | if(orcSHT->sh_size == 0)
354 | continue;
355 |
356 | if(orcSHT->sh_type == SHT_REL){
357 | orcREL = (Elf_Rel *) (orcptr + orcSHT->sh_offset);
358 | } else {
359 | orcRELA = (Elf_Rela *) (orcptr + orcSHT->sh_offset);
360 | }
361 |
362 | printf("\n[+] Fuzzing the relocations section %s with %d %s entries\n",
363 | orcptr + orcshstrtab_offset + orcSHT->sh_name, (unsigned int) (orcSHT->sh_size / orcSHT->sh_entsize),
364 | orcSHT->sh_type == SHT_REL ? "SHT_REL" : "SHT_RELA");
365 | fprintf(logfp, "\n[+] Fuzzing the relocations section %s with %d %s entries\n",
366 | orcptr + orcshstrtab_offset + orcSHT->sh_name, (unsigned int) (orcSHT->sh_size / orcSHT->sh_entsize),
367 | orcSHT->sh_type == SHT_REL ? "SHT_REL" : "SHT_RELA");
368 |
369 | for(entry = 0; entry < orcSHT->sh_size / orcSHT->sh_entsize; entry++){
370 | fuzz_rel();
371 |
372 | fuzzed_flag = 1;
373 |
374 | if(orcSHT->sh_type == SHT_REL)
375 | orcREL++;
376 | else
377 | orcRELA++;
378 | }
379 | }
380 |
381 | if(!fuzzed_flag){
382 | printf("\n[!] No SHT_REL nor SHT_RELA sections found!\n");
383 | fprintf(logfp, "\n[!] No SHT_REL nor SHT_RELA sections found!\n");
384 | }
385 | }
386 |
387 | if(mode & SYM){
388 | verifySHT();
389 | orcSHT = orcOrigSHT;
390 |
391 | fuzzed_flag = 0;
392 | entry = 0;
393 |
394 | for(secnum = 0; secnum < orcHDR->e_shnum; secnum++, orcSHT++){
395 | if(orcSHT->sh_type != SHT_SYMTAB && orcSHT->sh_type != SHT_DYNSYM)
396 | continue;
397 |
398 | if(orcSHT->sh_size == 0)
399 | continue;
400 |
401 | linkstrtab_section = *(Elf_Shdr *) (orcptr + orcHDR->e_shoff + (orcSHT->sh_link * sizeof(Elf_Shdr)));
402 | linkstrtab_offset = linkstrtab_section.sh_offset;
403 |
404 | elfSYM = (Elf_Sym *) (elfptr + orcSHT->sh_offset);
405 | orcSYM = (Elf_Sym *) (orcptr + orcSHT->sh_offset);
406 |
407 | printf("\n[+] Fuzzing the Symbol Table %s with %d entries\n",
408 | orcptr + orcshstrtab_offset + orcSHT->sh_name, (unsigned int) (orcSHT->sh_size / orcSHT->sh_entsize));
409 | fprintf(logfp, "\n[+] Fuzzing the Symbol Table %s with %d entries\n",
410 | orcptr + orcshstrtab_offset + orcSHT->sh_name, (unsigned int) (orcSHT->sh_size / orcSHT->sh_entsize));
411 |
412 | for(entry = 0; entry < orcSHT->sh_size / orcSHT->sh_entsize; entry++, elfSYM++, orcSYM++){
413 | fuzz_sym();
414 |
415 | fuzzed_flag = 1;
416 | }
417 | }
418 |
419 | if(!fuzzed_flag){
420 | printf("\n[!] No SHT_SYMTAB nor SHT_DYNSYM sections found!\n");
421 | fprintf(logfp, "\n[!] No SHT_SYMTAB nor SHT_DYNSYM sections found!\n");
422 | }
423 | }
424 |
425 | if(mode & DYN){
426 | verifyPHT();
427 | verifySHT();
428 | orcSHT = orcOrigSHT;
429 |
430 | fuzzed_flag = 0;
431 | entry = 0;
432 |
433 | for(secnum = 0; secnum < orcHDR->e_shnum; secnum++, orcSHT++){
434 | if(orcSHT->sh_type != SHT_DYNAMIC)
435 | continue;
436 |
437 | if(orcSHT->sh_size == 0)
438 | continue;
439 |
440 | linkstrtab_section = *(Elf_Shdr *) (orcptr + orcHDR->e_shoff + (orcSHT->sh_link * sizeof(Elf_Shdr)));
441 | linkstrtab_offset = linkstrtab_section.sh_offset;
442 |
443 | elfOrigDYN = (Elf_Dyn *) (elfptr + orcSHT->sh_offset);
444 | elfDYN = elfOrigDYN;
445 | orcDYN = (Elf_Dyn *) (orcptr + orcSHT->sh_offset);
446 |
447 | printf("\n[+] Fuzzing the Dynamic section %s with %d entries\n",
448 | orcptr + orcshstrtab_offset + orcSHT->sh_name, (unsigned int) (orcSHT->sh_size / orcSHT->sh_entsize));
449 | fprintf(logfp, "\n[+] Fuzzing the Dynamic section %s with %d entries\n",
450 | orcptr + orcshstrtab_offset + orcSHT->sh_name, (unsigned int) (orcSHT->sh_size / orcSHT->sh_entsize));
451 |
452 | for(entry = 0; entry < orcSHT->sh_size / orcSHT->sh_entsize; entry++, elfDYN++, orcDYN++){
453 | fuzz_dyn();
454 |
455 | fuzzed_flag = 1;
456 |
457 | if(elfDYN->d_tag == DT_NULL)// End of _DYNAMIC[]. Trust in elfDYN, orcDYN->d_tag = NULL might have been changed
458 | break;
459 | }
460 | }
461 |
462 | if(!fuzzed_flag){
463 | printf("\n[!] No SHT_DYNAMIC section found!\n");
464 | fprintf(logfp, "\n[!] No SHT_DYNAMIC section found!\n");
465 | }
466 | }
467 |
468 | if(mode & NOTE){
469 | verifySHT();
470 | orcSHT = orcOrigSHT;
471 |
472 | fuzzed_flag = 0;
473 | entry = 0;
474 |
475 | for(secnum = 0; secnum < orcHDR->e_shnum; secnum++, orcSHT++){
476 | if(orcSHT->sh_type != SHT_NOTE)
477 | continue;
478 |
479 | if(orcSHT->sh_size == 0)
480 | continue;
481 |
482 | printf("\n[+] Fuzzing the Note section %s with %d bytes\n",
483 | orcptr + orcshstrtab_offset + orcSHT->sh_name, (unsigned int) orcSHT->sh_size);
484 | fprintf(logfp, "\n[+] Fuzzing the Note section %s with %d bytes\n",
485 | orcptr + orcshstrtab_offset + orcSHT->sh_name, (unsigned int) orcSHT->sh_size);
486 |
487 | elfNOTE = (Elf_Nhdr *) (elfptr + orcSHT->sh_offset);
488 | orcNOTE = (Elf_Nhdr *) (orcptr + orcSHT->sh_offset);
489 |
490 | fuzz_note();
491 |
492 | fuzzed_flag = 1;
493 | }
494 |
495 | if(!fuzzed_flag){
496 | printf("\n[!] No SHT_NOTE section found!\n");
497 | fprintf(logfp, "\n[!] No SHT_NOTE section found!\n");
498 | }
499 | }
500 |
501 | if(mode & STRS){
502 | verifySHT();
503 | orcSHT = orcOrigSHT;
504 |
505 | fuzzed_flag = 0;
506 |
507 | for(secnum = 0; secnum < orcHDR->e_shnum; secnum++, orcSHT++){
508 | if(orcSHT->sh_type != SHT_STRTAB)
509 | continue;
510 |
511 | // Metadata dependencies
512 | if(secnum == orcHDR->e_shstrndx)
513 | if(mode & (SHT | NOTE | DYN | SYM | REL))
514 | if(rand() % 3 < 2)
515 | continue;
516 |
517 | if(orcSHT->sh_size == 0)
518 | continue;
519 |
520 | printf("\n[+] Fuzzing the String Table %s with %d bytes\n",
521 | orcptr + orcshstrtab_offset + orcSHT->sh_name, (unsigned int) orcSHT->sh_size);
522 | fprintf(logfp, "\n[+] Fuzzing the String Table %s with %d bytes\n",
523 | orcptr + orcshstrtab_offset + orcSHT->sh_name, (unsigned int) orcSHT->sh_size);
524 |
525 | orcSTRS = (char *) (orcptr + orcSHT->sh_offset);
526 |
527 | fuzz_strs();
528 |
529 | fuzzed_flag = 1;
530 | }
531 |
532 | if(!fuzzed_flag){
533 | printf("\n[!] No SHT_STRTAB section found!\n");
534 | fprintf(logfp, "\n[!] No SHT_STRTAB section found!\n");
535 | }
536 | }
537 |
538 | if(mode & SHT){
539 | verifySHT();
540 | orcSHT = orcOrigSHT;
541 |
542 | printf("\n[+] Fuzzing the Section Header Table with %d entries\n", orcHDR->e_shnum);
543 | fprintf(logfp, "\n[+] Fuzzing the Section Header Table with %d entries\n", orcHDR->e_shnum);
544 |
545 | fuzz_sht();
546 | }
547 |
548 | if(mode & PHT){
549 | verifyPHT();
550 | orcPHT = orcOrigPHT;
551 |
552 | printf("\n[+] Fuzzing the Program Header Table with %d entries\n", orcHDR->e_phnum);
553 | fprintf(logfp, "\n[+] Fuzzing the Program Header Table with %d entries\n", orcHDR->e_phnum);
554 |
555 | fuzz_pht();
556 | }
557 |
558 | if(mode & HDR){
559 | printf("\n[+] Fuzzing the Elf Header\n");
560 | fprintf(logfp, "\n[+] Fuzzing the Elf Header\n");
561 |
562 | fuzz_hdr();
563 | }
564 |
565 | // Reflect the changes in filesystem
566 | if(msync(orcptr, 0, MS_SYNC) == -1){
567 | perror("msync");
568 | munmap(orcptr, elfstatinfo.st_size);
569 | close(orcfd);
570 | continue;
571 | }
572 |
573 | munmap(orcptr, elfstatinfo.st_size);
574 |
575 | close(orcfd);
576 |
577 | usleep(20000);
578 | }
579 |
580 | stop_logger(logfp);
581 |
582 | printf("\n[+] Fuzzing process finished\n");
583 | printf("[+] Orcs (malformed ELFs) saved in '%s/'\n", dirname);
584 | printf("[+] Detailed fuzzing report: '%s/%s'\n", dirname, logfname);
585 |
586 | munmap(elfptr, elfstatinfo.st_size);
587 |
588 | free(dirname_orcfname);
589 |
590 | exit(EXIT_SUCCESS);
591 | }
592 |
593 | void usage(const char *self)
594 | {
595 | banner();
596 |
597 | printf("Usage: %s [-n num -l likelihood -q]\n", self);
598 | printf("\t:\n");
599 | printf("\t\t-a Autodetect (fuzz according to e_type except -H [the header])\n");
600 | printf("\t\t-H ELF header\n");
601 | printf("\t\t-S Section Header Table\n");
602 | printf("\t\t-P Program Header Table\n");
603 | printf("\t\t-D Dynamic section\n");
604 | printf("\t\t-s Symbols Table(s)\n");
605 | printf("\t\t-R Relocations Table(s)\n");
606 | printf("\t\t-N Notes section\n");
607 | printf("\t\t-Z Strings Tables\n");
608 | printf("\t\t-A All of the above (except -a [Autodetect])\n");
609 | printf("\t\t-B All of the above (except -a [Autodetect] and -H [ELF Header])\n");
610 | printf("\t-n Number of new fuzzed ELF files (orcs) to create (default: %d)\n", n);
611 | printf("\t-l Likelihood (given in %% from 1-100) of the execution of each fuzzing rule (default: %d%%)\n", likelihood);
612 | printf("\t-q Quiet mode (doesn't print to STDOUT every executed fuzzing rule)\n");
613 |
614 | exit(EXIT_SUCCESS);
615 | }
616 |
617 | void banner()
618 | {
619 | srand(getseed());
620 |
621 | printf("%s", logo);
622 | printf("%s", banners[rand() % 5]);
623 |
624 | putchar('\n');
625 | }
626 |
627 | int elf_identification(int fd)
628 | {
629 | Elf_Ehdr header;
630 |
631 | if(read(fd, &header, sizeof(header)) == -1){
632 | perror("elf_identification: read");
633 | return 0;
634 | }
635 |
636 | return memcmp(&header.e_ident[EI_MAG0], ELFMAG, SELFMAG) == 0;
637 | }
638 |
639 | void verifySHT()
640 | {
641 | if(elfHDR->e_shoff == 0 || elfHDR->e_shnum == 0){
642 | printf("[-] No Section Header Table found (necessary for fuzzing) !\n");
643 | printf("[-] Quitting...\n");
644 | munmap(elfptr, elfstatinfo.st_size);
645 | exit(EXIT_FAILURE);
646 | }
647 | }
648 |
649 | void verifyPHT()
650 | {
651 | if(elfHDR->e_phoff == 0 || elfHDR->e_phnum == 0){
652 | printf("[-] No Program Header Table found (necessary for fuzzing) !\n");
653 | printf("[-] Quitting...\n");
654 | munmap(elfptr, elfstatinfo.st_size);
655 | exit(EXIT_FAILURE);
656 | }
657 | }
658 |
--------------------------------------------------------------------------------
/jni/src/melkor.h:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #ifndef __ANDROID_API__
5 | #include
6 | #else
7 | #include
8 | #include "lc_elf.h"
9 | #endif
10 |
11 | #define VERSION "v1.0"
12 |
13 | #define SWAP32(v) ((((v) & 0x000000ff) << 24) | \
14 | (((v) & 0x0000ff00) << 8) | \
15 | (((v) & 0x00ff0000) >> 8) | \
16 | (((v) & 0xff000000) >> 24))
17 |
18 | /* FUZZING MODES */
19 | #define AUTO (1 << 0) // Autodetect (based on e_type)
20 | #define HDR (1 << 1) // Elf Header
21 | #define SHT (1 << 2) // Section Header Table
22 | #define PHT (1 << 3) // Program Header Table
23 | #define SYM (1 << 4) // Symbols Table
24 | #define DYN (1 << 5) // Dynamic info
25 | #define REL (1 << 6) // Relocation data
26 | #define NOTE (1 << 7) // Notes section
27 | #define STRS (1 << 8) // Strings in the file
28 | #define ALL (HDR | SHT | PHT | SYM | DYN | REL | NOTE | STRS)
29 | #define ALLB (SHT | PHT | SYM | DYN | REL | NOTE | STRS)
30 |
31 |
32 | /* -DDEBUG was deleted from CFLAGS in Makefile.
33 | Add -DDEBUG if you want to print extra info.
34 | */
35 | #ifdef DEBUG
36 | #define debug(...) if(!quiet) printf(__VA_ARGS__)
37 | #else
38 | #define debug(...) //
39 | #endif
40 |
41 |
42 | /* Function pointer type 'func_ptr'.
43 | It will be used to create arrays of function pointers in fuzz_*.c
44 | */
45 | typedef int (*func_ptr)(void);
46 |
47 | #ifndef __ANDROID_API__
48 | int PAGESIZE; // Set at runtime with getpagesize() in melkor.c
49 | #endif
50 |
51 | #ifndef PT_GNU_STACK
52 | #define PT_GNU_STACK 0x6474e551 // Indicates executable stack
53 | #endif
54 |
55 | #ifndef PT_GNU_RELRO
56 | #define PT_GNU_RELRO 0x6474e552 // Read-only after relocation
57 | #endif
58 |
59 | #ifndef PT_PAX_FLAGS
60 | #define PT_PAX_FLAGS 0x65041580 // PAX Flags
61 | #endif
62 |
63 | // SHT_GNU_*
64 | #ifndef SHT_GNU_ATTRIBUTES
65 | #define SHT_GNU_ATTRIBUTES 0x6ffffff5
66 | #endif
67 |
68 | #ifndef SHT_GNU_HASH
69 | #define SHT_GNU_HASH 0x6ffffff6
70 | #endif
71 |
72 | #ifndef SHT_GNU_LIBLIST
73 | #define SHT_GNU_LIBLIST 0x6ffffff7
74 | #endif
75 |
76 | #ifndef SHT_GNU_verdef
77 | #define SHT_GNU_verdef 0x6ffffffd
78 | #endif
79 |
80 | #ifndef SHT_GNU_verneed
81 | #define SHT_GNU_verneed 0x6ffffffe
82 | #endif
83 |
84 | #ifndef SHT_GNU_versym
85 | #define SHT_GNU_versym 0x6fffffff
86 | #endif
87 |
88 | /* ELF STUFF */
89 | /*** 32 - 64 BITS COMPAT ***/
90 | #if defined(__i386__) /**** x86 ****/
91 | // Data Types
92 | #define Elf_Half Elf32_Half
93 | #define Elf_Word Elf32_Word
94 | #define Elf_Sword Elf32_Sword
95 | #define Elf_Xword Elf32_Xword
96 | #define Elf_Sxword Elf32_Sxword
97 | #define Elf_Addr Elf32_Addr
98 | #define Elf_Off Elf32_Off
99 | #define Elf_Section Elf32_Section
100 |
101 | // Data Structs
102 | #define Elf_Ehdr Elf32_Ehdr
103 | #define Elf_Shdr Elf32_Shdr
104 | #define Elf_Sym Elf32_Sym
105 | #define Elf_Rel Elf32_Rel
106 | #define Elf_Rela Elf32_Rela
107 | #define Elf_Phdr Elf32_Phdr
108 | #define Elf_Dyn Elf32_Dyn
109 | #define Elf_Nhdr Elf32_Nhdr
110 |
111 | // Macros
112 | #define ELF_ST_TYPE ELF32_ST_TYPE
113 | #define ELF_ST_BIND ELF32_ST_BIND
114 | #define ELF_ST_INFO ELF32_ST_INFO
115 | #define ELF_ST_VISIBILITY ELF32_ST_VISIBILITY
116 | #define ELF_R_TYPE ELF32_R_TYPE
117 | #define ELF_R_SYM ELF32_R_SYM
118 | #define ELF_R_INFO ELF32_R_INFO
119 |
120 | #define HEX "%.8x"
121 |
122 | #elif defined(__x86_64__) /**** x86_64 ****/
123 | // Data Types
124 | #define Elf_Half Elf64_Half
125 | #define Elf_Word Elf64_Word
126 | #define Elf_Sword Elf64_Sword
127 | #define Elf_Xword Elf64_Xword
128 | #define Elf_Sxword Elf64_Sxword
129 | #define Elf_Addr Elf64_Addr
130 | #define Elf_Off Elf64_Off
131 | #define Elf_Section Elf64_Section
132 |
133 | // Data Structs
134 | #define Elf_Ehdr Elf64_Ehdr
135 | #define Elf_Shdr Elf64_Shdr
136 | #define Elf_Sym Elf64_Sym
137 | #define Elf_Rel Elf64_Rel
138 | #define Elf_Rela Elf64_Rela
139 | #define Elf_Phdr Elf64_Phdr
140 | #define Elf_Dyn Elf64_Dyn
141 | #define Elf_Nhdr Elf64_Nhdr
142 |
143 | // Macros
144 | #define ELF_ST_TYPE ELF64_ST_TYPE
145 | #define ELF_ST_BIND ELF64_ST_BIND
146 | #define ELF_ST_INFO ELF64_ST_INFO
147 | #define ELF_ST_VISIBILITY ELF64_ST_VISIBILITY
148 | #define ELF_R_TYPE ELF64_R_TYPE
149 | #define ELF_R_SYM ELF64_R_SYM
150 | #define ELF_R_INFO ELF64_R_INFO
151 |
152 | #define HEX "%.16lx"
153 |
154 | #elif defined(__ANDROID_API__) /**** Android ****/
155 | // Data Types
156 | #define Elf_Half Elf32_Half
157 | #define Elf_Word Elf32_Word
158 | #define Elf_Sword Elf32_Sword
159 | #define Elf_Xword Elf32_Xword
160 | #define Elf_Sxword Elf32_Sxword
161 | #define Elf_Addr Elf32_Addr
162 | #define Elf_Off Elf32_Off
163 | #define Elf_Section Elf32_Section
164 |
165 | // Data Structs
166 | #define Elf_Ehdr Elf32_Ehdr
167 | #define Elf_Shdr Elf32_Shdr
168 | #define Elf_Sym Elf32_Sym
169 | #define Elf_Rel Elf32_Rel
170 | #define Elf_Rela Elf32_Rela
171 | #define Elf_Phdr Elf32_Phdr
172 | #define Elf_Dyn Elf32_Dyn
173 | #define Elf_Nhdr Elf32_Nhdr
174 |
175 | // Macros
176 | #define ELF_ST_TYPE ELF32_ST_TYPE
177 | #define ELF_ST_BIND ELF32_ST_BIND
178 | #define ELF_ST_INFO ELF32_ST_INFO
179 | #define ELF_ST_VISIBILITY ELF32_ST_VISIBILITY
180 | #define ELF_R_TYPE ELF32_R_TYPE
181 | #define ELF_R_SYM ELF32_R_SYM
182 | #define ELF_R_INFO ELF32_R_INFO
183 |
184 | #define HEX "%.8x"
185 | #else
186 | #error "Unsupported arch !"
187 | #endif
188 |
189 |
190 | /* PROTOTYPES */
191 | void usage(const char *);
192 | void banner();
193 | int elf_identification(int);
194 | void verifySHT(void);
195 | void verifyPHT(void);
196 |
197 | FILE *start_logger(char *, char *);
198 | void stop_logger(FILE *);
199 |
200 | void fuzz_hdr(void);
201 | void fuzz_sht(void);
202 | void fuzz_pht(void);
203 | void fuzz_sym(void);
204 | void fuzz_dyn(void);
205 | void fuzz_rel(void);
206 | void fuzz_note(void);
207 | void fuzz_strs(void);
208 |
209 | unsigned int getseed(void);
210 | Elf_Addr getElf_Addr(void);
211 | Elf_Off getElf_Off(void);
212 | Elf_Word getElf_Word(void);
213 | Elf_Xword getElf_Xword(void);
214 | Elf_Half getElf_Half(void);
215 | Elf_Section getElf_Section(void);
216 | char *get_fmt_str(void);
217 | char *get_fuzzed_path(void);
218 |
219 | Elf_Section findSectionIndexByName(char *);
220 | void fuzzName(void);
221 | void fuzzSize(void);
222 | void fuzzEntSize(void);
223 | void fuzzFlags(void);
224 | void fuzzAddrAlign(void);
225 |
226 | Elf_Addr get_d_ptr_by_d_tag(Elf_Sword);
227 | Elf_Word get_d_val_by_d_tag(Elf_Sword);
--------------------------------------------------------------------------------
/jni/src/numbers.h:
--------------------------------------------------------------------------------
1 | int int_l33t[] = {
2 | 0xB16B00B5, // ( * ) ( * )
3 | 0x0DEFACED,
4 | 0XDEADFACE,
5 | 0xCAFED00D,
6 | 0xFEE1DEAD,
7 | 0x0D15EA5E,
8 | 0xDEADC0DE,
9 | 0xBAD0C0DE,
10 | 0xDEFECA7E,
11 | 0xDEFEC8ED,
12 | 0x600DCAFE,
13 | 0x00031337,
14 | };
15 |
16 | short short_l33t[] = {
17 | 0xDEAD, 0xBABE,
18 | 0xCAFE, 0xF00D,
19 | 0xBEEF, 0xC0DE,
20 | 0xFACE, 0x0BAD,
21 | 0x1337, 0xD00D,
22 | 0x0FA6, 0xB00B,
23 | };
24 |
25 | Elf_Addr key_Addr[] = {
26 | 0x00000000, // Zero page
27 | 0x00400000,
28 | 0x08048000,
29 | 0x40000000, // 1GB
30 | 0x80000000, // 2GB
31 | 0x81000000,
32 | 0xc0000000, // 3GB
33 | 0xc1000000,
34 | 0xd0000000,
35 | };
36 |
37 | // Could be used as short by shifting 16 bits (E.g. int_b0f[0] >> 16 == 0x7fff)
38 | int int_b0f[] = {
39 | 0x7fffffff, // INT_MAX
40 | 0xffffffff, // UINT_MAX (-1 for signed vars)
41 | 0x80000000, // Negative value for signed vars (MSB = 1)
42 | 0xc0000000,
43 | 0xff00ff00,
44 | 0xffff0000,
45 | };
46 |
47 | int common_b0f[] = {
48 | 0x41424344, // INC EAX; INC EBX; INC ECX; INC EDX
49 | 0x41414141, // INC EAX * 4
50 | 0x42424242, // INC EBX * 4
51 | 0x43434343, // INC ECX * 4
52 | 0x44444444, // INC EDX * 4
53 | 0x90909090, // NOP
54 | 0xcccccccc, // INT 3
55 | };
56 |
57 | const char *fuzz_paths[] = {
58 | "orcs_libfoo.so/",
59 | "././../.././...",
60 | "/;;/;//..",
61 | "\\//\\//",
62 | "~/~~~//",
63 | "*/!/*",
64 | "$xX",
65 | ":::",
66 | "/#)",
67 | "$$",
68 | "//",
69 | "\\",
70 | "~",
71 | "*",
72 | "/",
73 | };
74 |
75 | const char *fmt_strs[] = {
76 | " %x ",
77 | " %n ",
78 | " %p ",
79 | };
80 |
--------------------------------------------------------------------------------
/jni/src/print_envp_vars.c:
--------------------------------------------------------------------------------
1 | /*
2 | * Melkor - An ELF File Format Fuzzer
3 | * Copyright (C) 2014 Alejandro Hernandez H. (nitr0us)
4 | *
5 | * Mexico
6 | */
7 |
8 | #include
9 | #include
10 |
11 | int main(int argc, char *argv[], char *envp[])
12 | {
13 | int index = 0;
14 |
15 | while(envp[index])
16 | if(strstr(envp[index], "LD_"))
17 | printf("$%s\n\n", envp[index++]);
18 | else
19 | index++;
20 |
21 | return 0;
22 | }
23 |
--------------------------------------------------------------------------------
/libs/armeabi/env1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anestisb/melkor-android/74d4ecd3719c21c92927c5a65bdf4318b547487d/libs/armeabi/env1
--------------------------------------------------------------------------------
/libs/armeabi/env2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anestisb/melkor-android/74d4ecd3719c21c92927c5a65bdf4318b547487d/libs/armeabi/env2
--------------------------------------------------------------------------------
/libs/armeabi/env3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anestisb/melkor-android/74d4ecd3719c21c92927c5a65bdf4318b547487d/libs/armeabi/env3
--------------------------------------------------------------------------------
/libs/armeabi/melkor:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anestisb/melkor-android/74d4ecd3719c21c92927c5a65bdf4318b547487d/libs/armeabi/melkor
--------------------------------------------------------------------------------
/libs/armeabi/print_envp_vars:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/anestisb/melkor-android/74d4ecd3719c21c92927c5a65bdf4318b547487d/libs/armeabi/print_envp_vars
--------------------------------------------------------------------------------