Created
March 17, 2014 20:01
-
-
Save LordJZ/9607042 to your computer and use it in GitHub Desktop.
simple guid packet unpacker
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "stdafx.h" | |
#include <ida.hpp> | |
#include <idp.hpp> | |
#include <loader.hpp> | |
#include <allins.hpp> | |
#include <name.hpp> | |
int __stdcall IDAP_init(void) | |
{ | |
// "metapc" represents x86 architecture | |
if (strncmp(inf.procName, "metapc", 8) != 0) | |
{ | |
error("Only PE and ELF binary type compiled for the x86 platform is supported, sorry."); | |
return PLUGIN_SKIP; | |
} | |
return PLUGIN_OK; | |
} | |
void __stdcall IDAP_term(void) | |
{ | |
// Stuff to do when exiting, generally you'd put any sort | |
// of clean-up jobs here. | |
return; | |
} | |
void decodeClientJam(ea_t addr) | |
{ | |
ea_t func = cmd.Op1.addr; | |
ea_t func_start = func; | |
int insn_size; | |
int i = 0; | |
while ((insn_size = decode_insn(func)) != 0) | |
{ | |
func += insn_size; | |
if (cmd.itype == NN_mov && cmd.Op1.type == 3 && cmd.Op1.reg == 0 && cmd.Op1.phrase == 0 | |
&& cmd.Op2.type == 5 && cmd.Op2.value) | |
{ | |
ea_t ctor_addr; | |
if (!get_many_bytes(cmd.Op2.value, &ctor_addr, 4)) | |
continue; | |
int size; | |
int j = 0; | |
while ((size = decode_insn(ctor_addr)) != 0) | |
{ | |
ctor_addr += size; | |
if (cmd.itype == NN_push && cmd.Op1.type == o_imm) | |
{ | |
msg("Opcode = %u\n", cmd.Op1.value); | |
char name[MAXSTR]; | |
if (!get_name(BADADDR, func_start, name, sizeof(name)-1)) | |
{ | |
msg("Cannot get name of %a\n", func_start); | |
return; | |
} | |
if (name[0] == 's' && name[1] == 'u' && name[2] == 'b') | |
{ | |
char name2[MAXSTR]; | |
sprintf(name2, "UserRouterClient_Constructor::%s_%u", name, cmd.Op1.value); | |
if (!set_name(func_start, name2)) | |
msg("Cannot set name of %a\n", func_start); | |
} | |
else | |
msg("Not renaming %a because of improper name", func_start); | |
return; | |
} | |
if (++j >= 20) | |
{ | |
msg("Cannot find push imm in %a :(\n", ctor_addr); | |
return; | |
} | |
} | |
} | |
if (++i >= 20) | |
{ | |
msg("Cannot find vtable in %a :(\n", addr); | |
return; | |
} | |
} | |
} | |
void decodePackedData(ea_t addr) | |
{ | |
int insn_size; | |
ea_t regbase = 65536; | |
uint16 reg = 0; | |
qvector<int> mask; | |
mask.reserve(16); | |
qvector<int> bytes; | |
bytes.reserve(16); | |
while ((insn_size = decode_insn(addr)) != 0) | |
{ | |
if (cmd.itype == NN_int3) | |
{ | |
insn_size = 0; | |
break; | |
} | |
else if (cmd.itype == NN_cmp) | |
{ | |
op_t src = cmd.Op1; | |
op_t op = cmd.Op2; | |
if (op.type == o_imm && op.value == 0 && src.type == o_displ) | |
{ | |
reg = src.phrase; | |
regbase = min(src.addr, regbase); | |
mask.push_back(src.addr); | |
} | |
} | |
else if (cmd.itype == NN_mov) | |
{ | |
op_t& op = cmd.Op2; | |
if (op.type == o_displ && op.phrase == reg) | |
bytes.push_back(op.addr); | |
} | |
//msg("Insn at %a (size=%d) is %d\n", addr, insn_size, cmd.itype); | |
addr += insn_size; | |
} | |
msg("mask=%d, bytes=%d\n", mask.size(), bytes.size()); | |
msg("protected override int[] MaskSequence { get { return new int[] { "); | |
for (int32 i = 0; i < int32(mask.size()); i += 8) | |
{ | |
for (int32 j = i + 8 - 1; j >= i; --j) | |
msg("%d, ", mask[j] - regbase); | |
} | |
msg("}; } }\n"); | |
msg("protected override int[] ByteSequence { get { return new int[] { "); | |
for (int32 i = 0; i < int32(bytes.size()); ++i) | |
msg("%d, ", bytes[i] - regbase); | |
msg("}; } }\n"); | |
} | |
// The plugin can be passed an integer argument from the plugins.cfg | |
// file. This can be useful when you want the one plug-in to do | |
// something different depending on the hot-key pressed or menu | |
// item selected. | |
void __stdcall IDAP_run(int arg) | |
{ | |
msg("Hello world!\n"); | |
ea_t addr = get_screen_ea(); | |
if (!decode_insn(addr)) | |
{ | |
msg("Unknown insn!\n"); | |
return; | |
} | |
if (cmd.itype == NN_call) | |
decodeClientJam(addr); | |
else | |
decodePackedData(addr); | |
} | |
// There isn't much use for these yet, but I set them anyway. | |
char IDAP_comment[] = "Unpacks data (lol)"; | |
char IDAP_help[] = "Buzzle Data Unpacker"; | |
// The name of the plug-in displayed in the Edit->Plugins menu. It can | |
// be overridden in the user's plugins.cfg file. | |
char IDAP_name[] = "Buzzle Data Unpacker"; | |
// The hot-key the user can use to run your plug-in. | |
char IDAP_hotkey[] = "Ctrl+J"; | |
// The all-important exported PLUGIN object | |
plugin_t PLUGIN = | |
{ | |
IDP_INTERFACE_VERSION, // IDA version plug-in is written for | |
PLUGIN_UNL, // Flags (see below) | |
IDAP_init, // Initialisation function | |
IDAP_term, // Clean-up function | |
IDAP_run, // Main plug-in body | |
IDAP_comment, // Comment – unused | |
IDAP_help, // As above – unused | |
IDAP_name, // Plug-in name shown in | |
// Edit->Plugins menu | |
IDAP_hotkey // Hot key to run the plug-in | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment