Serial fault injection in binary code

This post is also available in: Russian

Target – cover code branches, that process memory allocation errors. Conditions – binary code analisys only.

Let’s analyze binary code that is result of this code compilation:

int foo( unsigned int size )
{
void *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e =NULL;

a = malloc( size );
if( !a )
{
LogErr( "error allocating a\n" );
return -1;
}

LogDbg( "%u bytes allocated\n", size );

b = malloc( size * 2 );
if( !b )
{
LogErr( "error allocating b\n" );
return -1;
}

LogDbg( "%u bytes allocated\n", size * 2 );

c = malloc( size * 3 );
if( !c )
{
LogErr( "error allocating c\n" );
return -1;
}

LogDbg( "%u bytes allocated\n", size * 3 );

d = malloc( size * 4 );
if( !d )
{
LogErr( "error allocating d\n" );
return -1;
}

LogDbg( "%u bytes allocated\n", size * 4 );

e  = malloc( size * 5 );
if( !e )
{
LogErr( "error allocating e\n" );
return -1;
}

LogDbg( "%u bytes allocated\n", size * 5 );

free( a );
free( b );
free( c );
free( d );
free( e );

return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
LogInfo( "Press enter, please ...\n" );
getchar();
if( foo( 100 ) )
{
LogErr( "Can't call foo with parameter 100\n" );
return -1;
}

LogDbg( "First call. Parameter 100\n" );

if( foo( 200 ) )
{
LogErr( "Can't call foo with parameter 100\n" );
return -1;
}

LogDbg( "Second call. Parameter 200\n" );

if( foo( 500 ) )
{
LogErr( "Can't call foo with parameter 100\n" );
return -1;
}

LogDbg( "Third call. Parameter 500\n" );

LogInfo( "\nPress enter, please ..\n" );
getchar();

return 0;
}

Call  foo( 10 ) using Dataflow.

faulttest_sub_1000( 10 )

Main function code is covered. This is module coverage estimation:

In next picture covered blocks are colored by yellow.

White blocks are executed only after memory allocation fault. There is no another way call this code. MaiWay helps execute this code blocks. Let’s use special macros for serial fault injection.

CHECK_WITH_FAULT_INJECT( !faulttest_sub_1000( 10 ) );

Little but very impotent coverage gain.

Blocks than were not covered before are colored by yellow now.

Done.

Program has some bugs. Error processing is wrong. There is no previous memory buffers freeing after memory allocation fault. It leads to memory leaks.  Maiway can find such bugs.  After each fault injection MaiWay check allocated memory buffers. Information about buffers than were  not freed are shown.

Press enter, please …

Dataflow:FaultFuzzee, (-,22) foo(): 100 bytes allocated
Dataflow:FaultFuzzee, (-,31) foo(): 200 bytes allocated
Dataflow:FaultFuzzee, (-,40) foo(): 300 bytes allocated
Dataflow:FaultFuzzee, (-,49) foo(): 400 bytes allocated
Dataflow:FaultFuzzee, (-,58) foo(): 500 bytes allocated
Dataflow:FaultFuzzee, (-,24) DllMain(): Need start faulttest_sub_1000
Dataflow:MaiwayDataflow, (-,73) SetupFaultInjectors(): functionAddress: 10001290, processID: 0xbc8, functionName: malloc, moduleName: C:\Work\svn\build\Release\bin\test\FaultTest.exe
Memory allocation. 10 bytes in no file at 1379074(0x150b02)
Dataflow:FaultFuzzee, (-,22) foo(): 10 bytes allocated
Memory allocation. 20 bytes in no file at 1379138(0x150b42)
Dataflow:FaultFuzzee, (-,31) foo(): 20 bytes allocated
Memory allocation. 30 bytes in no file at 1379234(0x150ba2)
Dataflow:FaultFuzzee, (-,40) foo(): 30 bytes allocated
Memory allocation. 40 bytes in no file at 1379330(0x150c02)
Dataflow:FaultFuzzee, (-,49) foo(): 40 bytes allocated
Memory allocation. 50 bytes in no file at 1379426(0x150c62)
Dataflow:FaultFuzzee, (-,58) foo(): 50 bytes allocated
g_mode 1
g_currentIteration 0
g_totalCounter 5
g_currentAllocation 0
Memory allocation. 10 bytes in no file at 1379074(0x150b02)
Make fault inject in
File: no file, line 1379074
Dataflow:FaultFuzzee, (-,18) foo(): Error! error allocating a
g_mode 1
g_currentIteration 1
g_totalCounter 5
g_currentAllocation 1
Memory allocation. 10 bytes in no file at 1379074(0x150b02)
Dataflow:FaultFuzzee, (-,22) foo(): 10 bytes allocated
Memory allocation. 20 bytes in no file at 1379138(0x150b42)
Make fault inject in
File: no file, line 1379138
Dataflow:FaultFuzzee, (-,27) foo(): Error! error allocating b
Memory chunk:
begin from 003F2CD0 size 10
allocated at line 1379074 in file:
no file
Dataflow:FaultFuzzee, (-,33) DllMain(): Fault! Assertion failed: !FreeAllMemory()
g_mode 1
g_currentIteration 2
g_totalCounter 5
g_currentAllocation 2
Memory allocation. 10 bytes in no file at 1379074(0x150b02)
Dataflow:FaultFuzzee, (-,22) foo(): 10 bytes allocated
Memory allocation. 20 bytes in no file at 1379138(0x150b42)
Dataflow:FaultFuzzee, (-,31) foo(): 20 bytes allocated
Memory allocation. 30 bytes in no file at 1379234(0x150ba2)
Make fault inject in
File: no file, line 1379234
Dataflow:FaultFuzzee, (-,36) foo(): Error! error allocating c
Memory chunk:
begin from 003F42D8 size 20
allocated at line 1379138 in file:
no file
Memory chunk:
begin from 003F2CD0 size 10
allocated at line 1379074 in file:
no file
Dataflow:FaultFuzzee, (-,33) DllMain(): Fault! Assertion failed: !FreeAllMemory()
g_mode 1
g_currentIteration 3
g_totalCounter 5
g_currentAllocation 3
Memory allocation. 10 bytes in no file at 1379074(0x150b02)
Dataflow:FaultFuzzee, (-,22) foo(): 10 bytes allocated
Memory allocation. 20 bytes in no file at 1379138(0x150b42)
Dataflow:FaultFuzzee, (-,31) foo(): 20 bytes allocated
Memory allocation. 30 bytes in no file at 1379234(0x150ba2)
Dataflow:FaultFuzzee, (-,40) foo(): 30 bytes allocated
Memory allocation. 40 bytes in no file at 1379330(0x150c02)
Make fault inject in
File: no file, line 1379330
Dataflow:FaultFuzzee, (-,45) foo(): Error! error allocating d
Memory chunk:
begin from 003F4430 size 30
allocated at line 1379234 in file:
no file
Memory chunk:
begin from 003F42D8 size 20
allocated at line 1379138 in file:
no file
Memory chunk:
begin from 003F2CD0 size 10
allocated at line 1379074 in file:
no file
Dataflow:FaultFuzzee, (-,33) DllMain(): Fault! Assertion failed: !FreeAllMemory()
g_mode 1
g_currentIteration 4
g_totalCounter 5
g_currentAllocation 4
Memory allocation. 10 bytes in no file at 1379074(0x150b02)
Dataflow:FaultFuzzee, (-,22) foo(): 10 bytes allocated
Memory allocation. 20 bytes in no file at 1379138(0x150b42)
Dataflow:FaultFuzzee, (-,31) foo(): 20 bytes allocated
Memory allocation. 30 bytes in no file at 1379234(0x150ba2)
Dataflow:FaultFuzzee, (-,40) foo(): 30 bytes allocated
Memory allocation. 40 bytes in no file at 1379330(0x150c02)
Dataflow:FaultFuzzee, (-,49) foo(): 40 bytes allocated
Memory allocation. 50 bytes in no file at 1379426(0x150c62)
Make fault inject in
File: no file, line 1379426
Dataflow:FaultFuzzee, (-,54) foo(): Error! error allocating e
Memory chunk:
begin from 003F4590 size 40
allocated at line 1379330 in file:
no file
Memory chunk:
begin from 003F4430 size 30
allocated at line 1379234 in file:
no file
Memory chunk:
begin from 003F42D8 size 20
allocated at line 1379138 in file:
no file
Memory chunk:
begin from 003F2CD0 size 10
allocated at line 1379074 in file:
no file
Dataflow:FaultFuzzee, (-,33) DllMain(): Fault! Assertion failed: !FreeAllMemory()
g_mode 1
g_currentIteration 5
g_totalCounter 5
g_currentAllocation 5
Dataflow:FaultFuzzee, (-,35) DllMain(): Done
Dataflow:FaultFuzzee, (-,36) DllMain(): faulttest_sub_1000 called
Dataflow:MaiwayDataflow, (-,115) CleanupFaultInjectors(): functionAddress: 78AB0233, processID: 0xbc8, functionName: malloc, moduleName: C:\Work\svn\build\Release\bin\test\FaultTest.exe