bmap bug

$ ./bmap --help 
invalid option: --help
try '--help' for help

If you have this bug you can download the fix here!

Introduction

Bmap is a data hiding tool that can utilize slack space in blocks to hide data. It was also last maintained in 2000 and didn’t want to work on my computer in 2017.

As per instructions, run make to build from source. Success! However, I then tried to run help.

$ ./bmap --help 
invalid option: --help
try '--help' for help

Oh, well.. uh.. what?

At first I thought it was the build setup, you know, computers have changed a bit in 17 years maybe something was outdated. But after playing about for a couple of hours and manually recompiling with certain options there was no change.

I then tried to look at the source code and debug.

All the options!

Here’s part of the data for the hard coded options:

static struct mft_option options[]={
    {"doc","autogenerate document ...",
        MOT_VENUM|MOF_SILENT,
        MO_VENUM_CAST{
            {"version","display version and exit",
                1, 2
            },
            {"help","display options and exit",
                3, 4
            },
            {"man","generate man page and exit",
                MOF_HIDDEN,MO_INT_CAST(BMAP_MAN)
            },
            {"sgml","generate SGML invocation info",
                MOF_HIDDEN,MO_INT_CAST(BMAP_SGML)
            },
            {NULL,NULL,0,MO_CAST(NULL)}
    }
},

(The 1,2,3,4 constants on line 5 and 6 have been modified for demonstration)
Yep, there’s flags and macros, Oh goodie. Where is this being parsed / matched?

venum_walk=(struct mft_option *)(option_walk->defval.d_venum);
while(venum_walk && venum_walk->name)
{
    mft_logf(MLOG_PROGRESS,"checking against %s",venum_walk->name);
    if(!strcmp(venum_walk->name,key))
    {
        mft_logf(MLOG_PROGRESS,"matched against an venum val");
        val=key;
    }
    venum_walk++;
}

Struct alignment conundrum

Ah yes, here. So what names are being printed out?

checking against version

Thats it? but there’s 4 defined options!

name: version
desc: display version and exit
type: 0
defval: 0

name: (null)
desc: help
type: 4218998
defval: 0

That’s not good, “help” should be the name, not the description, how did that get unaligned?

size of struct mft_venum: 24

It’s 24 bytes, but the data from the initial option array is packed into 32 bytes!

name_ptr: 5060400000000000
desc_ptr: 5860400000000000
type: 0100000000000000
defval: 0200000000000000

Because of this, the defval is treated as the start of the next entry
name: 0x2

Fix – Computers are hard

At first I didn’t know why this was happening; I tried to think of all the changes computers have gone through in 17 years, then I thought about architecture. My machine is 64-bit, but the original author in 1998 probably had a 32-bit machine. So forcing gcc to compile for 32-bit mode fixes the alignment issue and all is well! Now I can hide data in slack space, thanks for the tool Daniel!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

WordPress.com.

Up ↑