Tuesday, September 27, 2016

What are 0xDEADBEEF, 0xFEEEFEEE, 0xCAFEFEED & co. ?

If you stumbled in this post looking looking for detailed answer for any of those mentioned in the title, without further ado, there are more complete explanation at:

But, if you want to know the big picture, read on ;-)

Chances are, you stumbled here after doing some hardcore debugging and found yourself baffled at the values that showed-up in the CPU registers or in the heap/stack memory. I found the first two values in the title (0xDEADBEEF and a variant of the second, i.e. 0xFEEEFEEEFEEEFEEE) while doing debugging in two different systems. The 0xDEADBEEF was on a System i (Power 5) system and the second one was on a Windows 64-bit machine.

All of these values are debugging-aid value, so to speak. It makes them very visible in the debugger (for those who already know). The purpose is to signal that something went wrong and to give an idea what possibly wrong, i.e. where the error possibly comes from, just with a glance on the debugger. For example, 0xDEADBEEF could mean either the program accessed unitialized (heap?) memory or a NULL pointer is encountered (pointing to uninitialized memory). Anyhow, it means something is wrong with one of your pointer. Similar case is indicated by 0xFEEEFEEE or its 64-bit variant.

These "readable" hexadecimal values are categorized as hexspeak because it looks like a "language" despite being hexadecimal value, i.e. you can read them aloud in English or other intended human language. The most hilarious of them all is 0xB16B00B5 ("Big Boobs"). I wonder who was the Hyper-V project manager at the time this Linux guest signature was determined at Microsoft LoL.

Tuesday, September 6, 2016

Debugging Cross-Compiled Windows Application (Executable and DLL)

I explained how to cross compile Windows application and DLL in Arch Linux in another post. Now, let's proceed on techniques that you can use to debug the result of the cross compilation. The general steps are as follows:

  1. Test the cross-compilation result in Wine (running on Linux of course). If the executable can run in Wine or the DLL can be loaded and (at least) partially executed, then, you may proceed to the next step. Otherwise, double check your cross-compiler as it may emit the wrong kind of executable.
  2. Run the executable (and if required all the DLLs) in Windows. First, without a debugger and then within a debugger, should an anomaly (or more) is found during the run(s).
  3. In the event that you need a debugger, make sure that the cross compiled version of the code contains debugging symbols. You can use "-g" switch in gcc/g++ to generate the debugging symbol in your GNU cross compiler. 
  4. In the event that you need a debugger, make sure your Windows debugger is recent enough that it can parse the debugging symbols in your cross-compiled executables and/or DLLs. Also, make sure that it can handle local variable(s), missing local variable debugging support or inability to display function parameter value(s) indicates that your debugger version probably isn't compatible with the cross-compiler. This is particularly true for gcc/g++ and gdb combination. For gcc/g++ cross compiler, you can use gdb from the nuwen "distribution". It has very recent GDB version. Note: I was caught off-guard by older version of gdb in Windows before because it was still quite usable.
To validate that your gdb version, make sure that your debugger output is similar to this:
Valid GDB output
As you can see in the screenshot above, you can inspect all local variable(s) while inside a breakpoint in a function that clearly has local variable. The debugger also shows the value(s) of the parameter passed to the function (where you set the breakpoint), including the function's implicit this parameter.  If you can't see any of that, it means you are using gdb which is incompatible with the gcc/g++ cross-compiler used to create the executable/DLL. Try finding newer gdb version than the one you're currently using.

You can use gdb "script" to carry-out semiautomatic debugging. The screenshot above shows how to use a gdb script, i.e. by using the source command in gdb. The source command basically tell gdb to parse the command file, i.e. the debugging script as if you're typing the debugging command yourself in gdb. See: https://sourceware.org/gdb/onlinedocs/gdb/Command-Files.html for more info on using command file in gdb. This is the gdb command file used in the screenshot above:
b main.cc:23
b main.cc:24
b main.cc:11
b main.cc:12

Hopefully, this post is helpful for those cross compiling applications to Windows from Linux.

Wednesday, August 17, 2016

Cross Compiling Windows Application and DLLs in (Arch) Linux

Cross compiling 32-bit and 64-bit Windows application in Linux is much easier these days than in the past. Thanks to the Mingw-w64 project.  It's even a little more easier in Arch Linux because most of what you need--including extensive amount of libraries--are already in AUR. For starter, install the cross compiler: https://www.archlinux.org/packages/community/x86_64/mingw-w64-gcc/. Then you can continue to install all other stuff (libraries and their dependencies) that you need. In most cases, you can just build and install the package by using the PKGBUILD file from AUR directly (via: cd ${src_dir}; makepkg -sri ). However, in some cases, you need to make adjustment(s) to the PKGBUILD file.

Let's focus on mingw-w64 in Arch Linux. There are several important matters that you need to take care of to cross compile opensource projects that uses Cmake in Arch Linux to build Windows executables and DLLs:
  • Opensource projects that uses CMAKE build system, need to use the mingw-w64-specific cmake (look at the example PKGBUILD for cmake below).
  • You need to set the include path to the cross compiler toolchain environment include path, not the host include path. 
This is an example PKGBUILD file for a simple Helloworld application that uses boost. It assumes that you have build and install the cross compiled boost DLL in your Arch Linux mingw-w64 environment.

_architectures="x86_64-w64-mingw32 i686-w64-mingw32"

rm -rvf build-*

for _arch in ${_architectures}; do
 mkdir -p build-${_arch} && pushd build-${_arch}
   ${_arch}-cmake ..
 make VERBOSE=1
The example above is the PKGBUILD file for the sample Helloworld project. You can clone the project over at: https://bitbucket.org/pinczakko/cross_hello_world.

There are also some things to take care if you cross compile opensource projects that uses autotools in Arch Linux to build Windows executables and DLLs:
  • Opensource projects that uses autotools build system, need to use the mingw-w64-specific configure script (look at the example PKGBUILD for configure below).
  • In some cases, you need to "fool" the libtool script to pass the "dynamic/static library integrity" check. You don't need to be afraid with this step because you could always use Linux file utility to verify the compiler output along with wine before testing/using it in real Windows installation.
This is an example PKGBUILD file for popt library:
# Maintainer: Sebastian Morr 
# Modified by Pinczakko for Mingw-w64 cross compilation to 64-bit Windows

pkgdesc="A commandline option parser (mingw-w64)"
options=(!strip !buildflags staticlibs)

_architectures="i686-w64-mingw32 x86_64-w64-mingw32"

prepare() {
  cd "$srcdir/${_pkgname}-$pkgver"
  patch -p1 -i ../0001-nl_langinfo.mingw32.patch
  patch -p1 -i ../197416.all.patch
  patch -p1 -i ../217602.all.patch
  patch -p1 -i ../278402-manpage.all.patch
  patch -p1 -i ../318833.all.patch
  patch -p1 -i ../356669.all.patch
  patch -p1 -i ../367153-manpage.all.patch
  patch -p1 -i ../get-w32-console-maxcols.mingw32.patch
  patch -p1 -i ../no-uid-stuff-on.mingw32.patch

build() {
  # We assume that libtool check on 64-bit Windows DLL is broken
  # in mingw-w64 Linux cross compiler. So, force it to pass all checks
  export lt_cv_deplibs_check_method='pass_all'

  cd "$srcdir/${_pkgname}-$pkgver"
  for _arch in ${_architectures}; do
    mkdir -p build-${_arch} && pushd build-${_arch}
 ${_arch}-configure --enable-shared --enable-static 

package () {
  for _arch in ${_architectures}; do
    cd "${srcdir}/${_pkgname}-${pkgver}/build-${_arch}"
    make install DESTDIR="${pkgdir}"
    rm -rf "${pkgdir}/usr/${_arch}/share/man"
    ${_arch}-strip -x -g "${pkgdir}/usr/${_arch}/bin/"*.dll
    ${_arch}-strip -g "${pkgdir}/usr/${_arch}/lib/"*.a

  install -D -m644 "${srcdir}/${_pkgname}-${pkgver}/COPYING" "$pkgdir/usr/share/licenses/$pkgname/LICENSE"

You can clone the files required to "cross build" popt library at: https://bitbucket.org/pinczakko/cross_mingw-w64-popt.

Hopefully, this is useful for those developing Windows application in Linux.

Wednesday, July 27, 2016

Java JAR Reverse Engineering Walkthrough

There are many ways to reverse engineer Java JAR file. However, I found the following steps are the fastest for me to understand the inner working of the Java code that I try to understand:
  1. Extract the target *.class file(s) from the Jar file with: jar -x command.
  2. If the class file(s) is/are recent one (>= java 1.5), use jadretro to condition the class file(s) before passing it through the jad java decompiler. jadretro is at: http://jadretro.sourceforge.net.
  3. Decompile the java class(es) with jad. You can download jad at: http://varaneckas.com/jad/.
  4. Use doxygen (http://www.stack.nl/~dimitri/doxygen/) plus graphviz(http://www.graphviz.org/) to generate the class inheritance and function call graph(s). This should give you an overview of how the class(es) works.
  5. Read the decompilation result as needed. I found that, step 4 will made this step easier as it gives you the hint(s) as to where to start reading the code.
Another approach is to use Radare2 (http://radare.org/r/). But, I've never used Radare for Java decompilation. Therefore, I don't know yet how mature its support. 

Anyway, sometimes interoperability needs forced us to rely on reverse engineering to get insight into how things work. This also applies to Java.