static knh_xblock_t* knh_generateWrapper(CTX ctx, void* callee, int argc, knh_ffiparam_t *argv) { //unsigned char *FUNCTION = (unsigned char*)knh_xmalloc(ctx, 1); knh_xblock_t *blk = get_unused_xblock(ctx); unsigned char *function = blk->block; size_t fidx = 0; // magick word WRITE_HEX(0x55); // push ebp WRITE_HEX(0x89); // mov esp->ebp WRITE_ASM(MOD_IMD, _ESP, _EBP); // incase we use ebp, store it. WRITE_HEX(0x53); // push ebx // we need stack argc * 8bytes at most size_t stacksize = argc * 8; // allocate stack (sub esp 0x38) WRITE_HEX(0x83); WRITE_HEX(0xec); WRITE_HEX((unsigned char)(stacksize + 0x8)); // before going, we need edx to be store; // mov edx --> -0x4(ebp) WRITE_HEX(0x89); // mov r+disp r WRITE_ASM(MOD_PLUS8, _EDX, _EBP); WRITE_HEX(0xfc); //now, process first argument; int i; knh_ffiparam_t *t; for (i = 0; i < argc; i++) { t = &(argv[i]); if (t->sfpidx != -1) { // if sfpidx == -1, its ret value; // prepare ebx (put sfp from edx); WRITE_HEX(0x89); WRITE_ASM(MOD_IMD, _EDX, _EBX); switch(t->type) { case CLASS_Tvoid: // do noting. break; case CLASS_Int: // its 64bit int //TODO: we need to call translater, but now, we ignore //TODO: assume we cast Int --> int; // add ebx[sfp] + sfpidx * 16; WRITE_HEX(0x83); //add WRITE_ASM(MOD_IMD, _EAX , _EBX); WRITE_HEX((unsigned char)(t->sfpidx * 16)); // move ivalue(offset is 8); WRITE_HEX(0x8b); // mov r+disp, r WRITE_ASM(MOD_PLUS8, _EAX, _EBX); WRITE_HEX(0x8); // move eax to local value //WRITE_HEX(0x89); //WRITE_ASM(MOD_IMD, _EBP, _EAX); // WRITE_HEX(0xf4); break; case CLASS_Float: WRITE_HEX(0x83); WRITE_ASM(MOD_IMD, _EAX, _EBX); WRITE_HEX((unsigned char)(t->sfpidx * 16)); // load fvalue; WRITE_HEX(0xdd);// fld 64bit WRITE_HEX(0x43);// eax WRITE_HEX(0x8); // offset // push it to eax; WRITE_HEX(0xdd); // fstp : store & pop 64 WRITE_HEX(0x1c); WRITE_HEX(0x24); break; default: break; } } else continue; // if its ret value } // now, call foreign function // NOT SURE??? since konoha is using FASTCALL, // call convension is always Fastcall. unsigned char default_disp = 0x8; unsigned char disp = 0x0; // argc contains ret value. remeber... // TODO :only for a single argument... for (i = argc - 1; i > 0; i--) { // push aruguments on the stack; // mov argument to eax! // TODO : now, we only consider 32 bit values if (argv[i].type == CLASS_Int) { function[fidx++] = 0x89; // mov r+disp r function[fidx++] = 0x45; // 0xXX(ebp) disp = default_disp + i * 4; disp = 0x100 - disp; function[fidx++] = disp; // -0x8 //move to esp function[fidx++] = 0x89; function[fidx++] = 0x04; function[fidx++] = 0x24; } } //now call. // call foreign function // intptr_t ucallee = (intptr_t)callee; // intptr_t next_addr = (intptr_t)function + (intptr_t)fidx + 5 /*for call instruction */; //intptr_t rel = (ucallee > next_addr) ? ucallee - next_addr : next_addr - ucallee; //rel = -rel; //unsigned char *src = (unsigned char*)&rel; // absolute call unsigned char *src = (unsigned char*)&callee; // mov this to eax; WRITE_HEX(0xb8); // mov to eax WRITE_HEX(src[0]); WRITE_HEX(src[1]); WRITE_HEX(src[2]); WRITE_HEX(src[3]); // now call WRITE_HEX(0xff); WRITE_HEX(0xd0); // function[fidx++] = 0xcc; // after calling, restore edx; // restore edx; WRITE_HEX(0x8b); WRITE_ASM(MOD_PLUS8, _EDX, _EBP); WRITE_HEX(0xfc); if (argv[0].sfpidx == -1) { switch(argv[0].type) { case CLASS_Tvoid: goto STEP_OUT; break; case CLASS_Int: // get return value, and give it to Konoha // ret value is on eax; // push eax function[fidx++] = 0x50; // push eax break; case CLASS_Float: // it is on FPU. we need no concern. break; } } // get rix (at 0x8(ebp)) --> eax WRITE_HEX(0x8b); // mov WRITE_ASM(MOD_PLUS8, _EAX, _EBP); // 0xXX(ebp) eax WRITE_HEX(0x8); // 8 // get edx --> ebx WRITE_HEX(0x89); WRITE_ASM(MOD_IMD, _EDX, _EBX); // ebx[sfp] + 16 * rix // first, 16 * rix = 2^4 * rix WRITE_HEX(0xc1); // shl WRITE_ASM(MOD_IMD, _ESP, _EAX); WRITE_HEX(0x4); // second, add eax to ebx; WRITE_HEX(0x01); //add WRITE_ASM(MOD_IMD, _EAX, _EBX); // add eax -> ebx; // now at ebx is pointing to sfp[K_RIX]; // copy retvalue to sfp[K_RIX].ivalue (offset is 0x8) // pop eax; // offset is different for each types if (argv[0].sfpidx == -1) { switch (argv[0].type) { case CLASS_Int: function[fidx++] = 0x58; // pop eax // mov eax --> 0x8(%ebx) function[fidx++] = 0x89; // mov r+disp r function[fidx++] = 0x43; // eax: ebx function[fidx++] = 0x8; // 0x8 break; case CLASS_Float: //fstpl 0x8(ebx) WRITE_HEX(0xdd); WRITE_ASM(MOD_PLUS8, _EBX, _EBX); WRITE_HEX(0x8); break; } } // from here, closing this function // close stack; add 0xXX esp STEP_OUT: WRITE_HEX(0x83); WRITE_HEX(0xc4); WRITE_HEX((unsigned char)(stacksize + 0x8)); // restore ebx WRITE_HEX(0x5b); // pop ebx WRITE_HEX(0x5d); // pop ebp; // ret $0x4 WRITE_HEX(0xc2); // ret WRITE_HEX(0x4); WRITE_HEX(0x0); // return function; return blk; }
/* * Handles a single serial number. This function takes the serial and computes * its SHA1. From that digest the SSID and the KEY can be derrived. If the SSID * matches the wanted SSID (from ctx->wanted_ssid) then the KEY will be printed. */ static void process_serial (ThreadCtx *ctx, const char *serial, size_t len) { WifiRouter **routers_iter; char is_key_computed = 0; char key [11]; /* Will hold the SHA1 in binary format */ unsigned char sha1_bin [SHA1_DIGEST_BIN_BYTES]; /* Now that the serial number is generated we can compute its corresponding key which is derived from its SHA1. */ SHA1(SHA1_BUFFER_TYPE(serial), len - 1, sha1_bin); for (routers_iter = ctx->routers; *routers_iter != NULL; ++routers_iter) { WifiRouter *router = *routers_iter; unsigned char *ssid_ptr; int cmp; /* The SSID is in the last bytes of the SHA1 when converted to hex */ ssid_ptr = &sha1_bin[SHA1_DIGEST_BIN_BYTES - SSID_BIN_LENGTH]; /* If this is the desired SSID then we compute the key */ cmp = memcmp(ssid_ptr, router->bin_ssid, SSID_BIN_LENGTH); if (cmp < 0) { /* The SSID is smaller than the first SSID to match, no need to continue */ return; } else if (cmp) { /* No match, try the next router */ continue; } /* The key is in the first 5 bytes of the SHA1 when converted to hex */ if (! is_key_computed) { size_t i; size_t pos = 0; for (i = 0; i < 5; ++i) { unsigned char c = sha1_bin[i]; WRITE_HEX(key, pos, c); pos += 2; } key[pos] = '\0'; is_key_computed = 1; } if (ctx->mutex != NULL) pthread_mutex_lock(ctx->mutex); if (ctx->debian_format) { printf( "iface speedkey inet dhcp\n" "\twpa-ssid %s%s\n" "\twpa-passphrase %s\n", router->type, router->hex_ssid, key ); } else { printf("Matched SSID %s, key: %s, serial: %s\n", router->hex_ssid, key, serial); } if (ctx->mutex != NULL) pthread_mutex_unlock(ctx->mutex); } }