Tutorials

Be creative!

Attaching your target

Follow the welcome to UI to select your session type: Local, Android, iOS, Remote – and your target process / package to spawn.

python3 dwarf.py

Or do it straight with the command line

# spawn /bin/man and inject agent.js
python3 dwarf.py -s scripts/agent.js /bin/man open

# android and windows support flag -bs to break at spawn
python3 dwarf.py -t android -bs com.twitter

Scripting

Hooks and breakpoints

var open = findExport('open');
Interceptor.attach(open, function(args) {
    log(args[0].readUtf8String());
});

putBreakpoint(open);

putBreakpoint('android.app.activity.onCreate');

putBreakpoint(0x1000);

putBreakpoint('open', function(args) {
    if (args[0].readUtf8String().indexOf('.json') >= 0) {
        return true;
    }

    return false;
});

Here if we want to break only at certain conditions – eventually editable through UI as well


Reaching a function in a target module

hooking module loaded, chain a break to an offset and read 32 bytes of the buffer pointed by register

hookModuleInitialization('xxx.so', function () {
    // grab the base
    const base = Process.findModuleByName('xxx.so').base;
    // log to ui
    console.log('base =: ' + base);

    // declare target ptr
    const payloadRecv = base.add(0x630FAE);
    // hook it
    Interceptor.attach(payloadRecv, function (args) {
        console.log('hook in');
        console.log(args[0].readByteArray(32));
    });

    // do not break - continue
    return -1;
});

Reaching initialization array pointers

Combining dwarf Android native onload with r2 js api to automate the reaching of initialization functions.

the most recent version of onload hooks in Android exists in Dwarf by attaching soinfo::call_constructor()

the register argument 0 holds the pointer of the current soinfo_struct

I did the parse of the struct until relevant things.

const soinfo_struct = 'ppppppppppppppppppppppppp phdr phnum base size dynamic ' +
	'next strtab symtab nbucket nchain bucket chain plt_got plt_rel plt_rel_count rel rel_count,' +
	' preinit_array preinit_array_count init_array init_array_count fini_array fini_array_count init_func fini_func';

hookModuleInitialization('libtarget.so', function () {
	var soinfo = this.context.x0;
	r2('s ' + soinfo);
	log(r2('pf ' + soinfo_struct));
	var p = JSON.parse(r2('pfj ' + soinfo_struct));

	var initArray = null;
	var initArraySize = 0;

	p.forEach(function (field) {
		if (field.name === 'init_array') {
			initArray = ptr(field.value);
		} else if (field.name === 'init_array_count') {
			initArraySize = field.value;
		}
	});

	if (initArray !== null) {
		log('\n\ninit array at: ' + initArray + '\nsize: ' + initArraySize);
		var functions = [];
		for (var i=0;i<initArraySize;i++) {
			functions.push(initArray.add(Process.pointerSize * i).readPointer());
		}
		log(functions);
	}
});