Skip to content

re-ws.pl

ReverseEngineering WorkStation

  • Home
  • Tutorials
  • Random
  • About

Tag: library

Docker image with just cURL

Posted on June 7, 2021 by Kamil (aka. v3l0c1r4pt0r)

Lately I play a bit with Docker containers. In a chain of problems that I have right now, I needed to have static cURL library on Debian. As it turned out linking cURL statically is not an easy task. Rather it causes a lot of problems, especially when trying this with packages available in Debian repos. After a long fight with these I decided to prepare my own distribution of cURL. But instead of creating usual deb package, I did it all on Docker and as a result, I have Docker image. In it I utilized possibilities of staged builds, where there can be few steps having in common only certain files. As a result I created base image, means the one created from scratch, where there are no other files, than the ones that we provide. So I provided only complete cURL install directory and musl libc to be able to run curl binary, as I did not want to tinker with cURL’s build system even more, than I did. Final image weights only ~1,5 MiB, so a result is really nice space saving compared to usual approach to Docker images. Inside, you can run curl binary separated from your operating system (to extent that Docker provides – remember, it is not virtualization!). Also it is possible to use libcurl to link your own binaries with it, this time completely statically!

As always, sources are on Github and this time there are also ready-to-use images on Docker Hub, so you can pull them directly, without need to build them. All instructions are on both pages and this is nothing unusual for any user of Docker, so I will not repeat myself here.

Posted in NewsTagged cURL, docker, hacking, library, Linux, softwareLeave a comment

LKV373A: crafting ELF

Posted on November 28, 2017 - October 17, 2019 by Kamil (aka. v3l0c1r4pt0r)

This article is part of series about reverse-engineering LKV373A HDMI extender. Other parts are available at:

  • Part 1: Firmware image format
  • Part 2: Identifying processor architecture
  • Part 3: Reverse engineering instruction set architecture
  • Part 4: Crafting ELF
  • Part 5: Porting objdump
  • Part 6: State of the reverse engineering
  • Part 7: radare2 plugin for easier reverse engineering of OpenRISC 1000 (or1k)

As we should now be able to follow any jump present in the code, it is now time to make analysis more automatic. My target tool for that purpose will be objdump. However, we still have firmware image as raw dump of memory. To be able to use objdump easily, we need to pack our firmware into some container understandable by objdump. Most obvious choice is ELF (Executable and Linkable Format) and this is what I am going to use.

For the purpose of packing data into ELF, I’ve made Python library that makes it easier. For now, it is able to split firmware image into sections, like .text or .data, so objdump will be able to disassembly only the parts of firmware that are in fact a code. Moreover, it can define symbols inside the binary, so it is possible to store information, where certain functions starts and ends, same for any variables, like strings. As of now, there is no CLI interface for the program. If it turns out that such interface is necessary (like for addition of many symbols), it will be added.

Library code can be downloaded from Github. Currently, any LKV373A-specific modifications to this library is stored on branch lkv373a, to not rubbish main – master branch. Throughout this tutorial, I assume, we are using code on this branch, so there might be some LKV373A-specifics, especially regarding enum types (i.e. processor architecture enum).

At this point, I need to warn, that I am not going to describe internal structure of ELF file, nor any features that might be visible from outside, like sections concept, so if you are not familiar with them, it is good time to learn about them, as it might be very difficult to understand, what I am writing about. There are many good resources explaining them. Ones I was using are: this blog post and this documentation.

Creating new ELF

Example code that creates brand new ELF file is as easy as:

 1 #!/usr/bin/python3
 2 # demo script for creating ELF
 3 import os
 4 from elf import *
 5 
 6 elf = ELF(e_machine=EM.EM_LKV373A)
 7 
 8 fp = os.open('lkv373a.fw.elf',os.O_CREAT|os.O_WRONLY)
 9 os.write(fp, bytes(elf))
10 os.close(fp)

This, at first does all necessary imports, then creates new ELF object in line 6, and, finally, converts it to bytes object and immediately writes to file descriptor. That’s it!

After this, you should get valid, empty ELF file for architecture called lkv373a, which, obviously does not exists and no other program know how to handle, but we are going to change that in future.

While creating ELF object, few things can be defined, in addition to architecture id. They are all described in documentation, I will mention near the end of this tutorial. You are also free to dig in structure of ELF object. There is no encapsulation in it and structure validation is very permissive, so even completely broken ELFs could be produced, if needed.

Adding section

Next step is to add some sections to our ELF file.

fw = os.open('LKV373A_TX_V3.0c_d_20161116_bin.bin',os.O_RDONLY)
fw_blob = os.read(fw, 0xffffffff)

irq_blob = fw_blob[:0x1000]
text_blob = fw_blob[0x7d100:0x7d100+0x0b53c0]
data_blob = fw_blob[0x0b53c0:0x0b53c0+0x102060]
smedia_blob = fw_blob[0x200000:0x200000+0x283105]

irq_id = elf.append_section('.irq',irq_blob,0)
txt_id = elf.append_section('.text',text_blob,0x7d100)
data_id = elf.append_section('.data',data_blob,0x0b53c0)
smedia_id = elf.append_section('.smedia',smedia_blob, 0x200000)

At first, I am extracting them from firmware image and then inserting them to ELF object. append_section is a handy wrapper to low-level modifications that must be done on ELF structure, hidden under what we can see as ELF instance (these low-level structures are, however still available to the user as ELF.Elf member).

Modifying section attributes

Ok, so now we have sections in our ELF file, ready to save to disk. Before that, one thing can yet be done: setting proper attributes. They tell readers, if program is able to write or execute sections of memory, among other features, I am going to ignore here. This might be useful, as some readers might be confused about what is code (text) and what is data. In our case, we have two text sections (.irq and .text), so we are going to set them executable flag (SHF_EXECINSTR). Furthermore, we will set SHF_ALLOC flag for any section that is going to be loaded into memory (so all of them).

This can be done with:

elf.Elf.Shdr_table[irq_id].sh_flags = SHF.SHF_ALLOC | SHF.SHF_EXECINSTR
elf.Elf.Shdr_table[txt_id].sh_flags = SHF.SHF_ALLOC | SHF.SHF_EXECINSTR
elf.Elf.Shdr_table[data_id].sh_flags = SHF.SHF_ALLOC
elf.Elf.Shdr_table[smedia_id].sh_flags = SHF.SHF_ALLOC

Adding segment

Segments are another concept, existing beside sections. They are stored in program header of ELF file and are somehow linked to section data. They allow to define another set of attributes to areas in memory. I don’t think they will be required to define, to perform analysis in objdump, but since at least one such program header, defining segment must exist in ELF file of type executable, there is interface similar to this for sections.

To define new segment, based on .text section, you can issue:

elf.append_segment(txt_id, flags='rx')

This also marks the segment as read and executable, but not writable.

Loading existing ELF

Loading existing ELF can be easily done from file with:

newelf, b = ELF.from_file('lkv373a.fw.elf')

Alternatively, it can also be loaded from bytes object:

fd = os.open('some.elf', os.O_RDONLY)
b = os.read(fd, 0xffff)
os.close(fd)
manualelf, b = Elf32.from_bytes(b)

In latter case, I assumed that os library is already imported into python.

Adding a symbol

This is very useful for making analysis of code. New symbol can be added using calls like:

elf.append_symbol('irq0', irq_id, 0, 0x44, STB.STB_GLOBAL, STT.STT_FUNC)
elf.append_symbol('sprintf', txt_id, 0x9b9f8-0x7d100, 0x78, STB.STB_GLOBAL,
        STT.STT_FUNC)
elf.append_symbol('thread_c_path', data_id, 0xba78a-0x0b53c0, 0xba7bb-0xba78a,
        STB.STB_LOCAL, STT.STT_OBJECT)

First call defines function of length 0x44 in .irq section. To do this, ID of .irq section must be known. Luckily, we want to add symbol at the beginning of the section, so as offset, 0 was provided.

In the second case, we also want to define a function, but now we only know absolute address of the function (0x9b9f8), but what we need to pass is offset in .text section. To achieve this, we need to subtract address of the start of .text section (0x7d100).

In the last example, we define a string as an object of certain address and length. Both address and length are computed by subtracting absolute addresses. This symbol will be marked as local, which is default behavior for append_symbol function.

Library documentation

There are many more things possible to do using makeelf library. What I showed here is mostly, what is possible using high-level wrappers, doing many things under the hood. But as there is also low-level interface, virtually anything is possible.

To make exploring interfaces easier, I’ve made doxygen documentation for most of the library. It can be found on my server, here. Feel free to use the library for anything you want.

Conclusion

The library presented here should allow us make one step further to easy to use reverse engineering environment. It will by the way allow to store new findings in easily-modifiable Python scripts.

What I showed in examples to library interfaces split LKV373A firmware image into 4 sections. At this moment I already know that there are at least 6 sections, where code and data are in two parts (forming ICDCDS layout, where I-irq, C-code and so on). Also there should be some more symbols possible to place at this moment.

If I succeed in porting objdump, or any other tool able to disassemble ELF file, next step would be to publish Python script, utilizing library presented here, that annotates LKV373A firmware. So stay tuned, I hope there will be many further interesting findings throughout this reversing process!

Posted in Reversing LKV373A, TutorialsTagged ELF, English, firmware, hacking, hardware, library, Python, Reverse EngineeringLeave a comment

[Import] Introducing libfatdino – low-level Linux library to handle FAT32 volumes at /dev file level

Posted on September 4, 2017 - September 4, 2017 by Kamil (aka. v3l0c1r4pt0r)

NOTE: This post was imported from my previous blog – v3l0c1r4pt0r.tk. It was originally published on 17th September 2013.

Today it’s finally time to introduce my first Linux project. Its main function is to provide all functions needed to handle block device formatted using FAT32 volume. For now it is early alpha providing only functions for reading. It also contain simple C++ demo that was used initially for testing. Main program repository is placed on github, so I hope all progress will be immediately uploaded and available for everyone. Whole library has been written in C with building scripts in make so it is possible to port it to every environment including BIOS which is as mentioned below one of its targets. Compilation should also be possible on environments other than Linux i.e. Windows. Important: library’s dependencies are glibc (Linux default so it shouldn’t be problem) and PCRE (found on most of the distributions) and there is no configure script as of now to check their presence so if you haven’t them you will get compilation error!

Starting to write this library I had 2 main goals. First one was to write read/write functions for use under Linux environment. This one will be achieved by completing this library. The second is to rewrite part of this lib responsible for reading to use it in pure BIOS environment. This goal will be the most important step to complete my another project that I won’t introduce here, because of really small amount of work done for now.

But you may ask: why FAT32, filesystem that really is the most ancient fs that is already in use? Answer for this question is relatively easy. The first fact that is in favor of FAT is its simplicity comparing to any modern filesystem that has features like permissions or access control lists. The other one is still considerable prevalence especially on every embedded application as cameras, phones (smart too), USB sticks.

Most of the code written here was based on Microsoft’s whitepaper entitled Microsoft Extensible Firmware Initiative FAT32 File System Specification. Few details that wasn’t included in that document is based on other people’s code found on Google so I couldn’t mention the exact names. The most interesting details that Microsoft’s whitepaper doesn’t contain is:

  • creation date and time values in directory entry structure
  • way that drivers (linux driver too) determine if file or directory that doesn’t contain Long File Name should be lowercase or uppercase
  • last access value encoding; that one is as of now still unsupported, I’ll try to add it after whole project is done

All functions that is already present in the lib has I think sufficiently detailed description on its header file. Their implementation is also present on other functions and on the demo app so I hope that it will not be problem to anyone to use it properly even though some caption in the demo are in Polish. The reason for that Polish strings is that demo was initially not designed to be public. To use that library some knowledge about FAT filesystem is required, because every function doesn’t contain all code needed to perform actions listed below, i.e. function that reads directory content has no code to list that directory and cannot follow cluster chain so that actions must be implemented by programmer that wants to use the lib. Of course following cluster chain is implemented in another function so there is no need to write it from scratch.

Functionalities implemented

  • reading a file
  • reading directory (with LFN support)
  • getting file/dir location based on its path in the filesystem
  • getting file’s properties

Functionalities to be implemented

  • writing to file
  • moving files
  • creating dirs
  • modifying directory entries
  • writing bootloader code to BPB/BS

Functions which operation isn’t visible to end user aren’t listed above so there is still lot of work to do.

Posted in UncategorizedTagged English, FAT, FAT32, library, LinuxLeave a comment

Tags

Android assembly busybox C CAN can-hacking cc-factory cmake compiler docker Dreamspark electronics English gcc hacking hardware JavaCard JCOP kernel KiCAD library Linux PC PCB pinout PKI polski programming Python radio Raspberry Pi Reverse Engineering RTL-SDR SDC SDM SDR smart card software tor tty UART UEFi Windows X.509 Xperia Pro

Recent Posts

  • PHP build for use bundled in Android applications
  • Running graphical apps inside Docker containers
  • Plugin architecture demo for Python projects
  • Authorizing adb connections from Android command line (and making other service calls from cli)
  • How to recover torrent from rtorrent meta files

Recent Comments

  • pomi on Playing with GF-07 GPS device
  • pomi on Playing with GF-07 GPS device
  • Hamdy Abumgata on Playing with GF-07 GPS device
  • Mousum Gogoi on Playing with GF-07 GPS device
  • Eason on Sniffing USB traffic with DSLogic logic analyzer into pcap file

Categories

  • News
  • Random
  • Reversing LKV373A
  • Setting up new v3 Hidden Service with ultimate security
  • Tutorials
  • Uncategorized
  • Understanding JCOP

Links

  • Me @ github
  • LKV373A Wiki
  • DevTomek

Archives

  • December 2024
  • November 2024
  • May 2024
  • July 2023
  • October 2022
  • August 2022
  • July 2021
  • June 2021
  • May 2021
  • December 2020
  • November 2020
  • October 2020
  • August 2020
  • December 2019
  • November 2019
  • October 2019
  • August 2019
  • July 2019
  • February 2019
  • November 2018
  • October 2018
  • June 2018
  • May 2018
  • March 2018
  • February 2018
  • January 2018
  • December 2017
  • November 2017
  • September 2017

Meta

  • Log in
  • Entries feed
  • Comments feed
  • WordPress.org
Proudly powered by WordPress | Theme: micro, developed by DevriX.