/* (C) 2003-2007 Willem Jan Hengeveld * Web: http://www.xs4all.nl/~itsme/ * http://wiki.xda-developers.com/ * * $Id: $ */ /* test code: auto l,m,n; l= newlist(); push(l, "abcde"); push(l, "test132"); push(l, "axyzz"); foreach("Message(\"l:... %s\\n\", x)", l); m= map("x=form(\"%d\",strlen(x))", l); foreach("Message(\"m:... %s\\n\", x)", m); n= grep("x=(substr(x,0,1)==\"a\")", l); foreach("Message(\"n:... %s\\n\", x)", n); Message("l: pop=%s\n", pop(l)); Message("l: pop=%s\n", pop(l)); Message("l: pop=%s\n", pop(l)); dellist(l); dellist(m); dellist(n); */ #include #include #include #include #include #include #include "boost/format.hpp" #include #include #include "pro.h" // for basic types. #include "ida.hpp" // for ida constants and types. #include "idp.hpp" // for interface version #include "netnode.hpp" // for RootNode #include "expr.hpp" // for IDCFuncs #include "idcextensions.h" #include "lists.h" const char idcargs_Beep[4]= { 0 }; error_t idaapi idc_Beep(value_t *argv,value_t *res) { MessageBeep(MB_OK); return eOk; } const char idcargs_newlist[4]= { 0 }; error_t idaapi idc_newlist(value_t *argv,value_t *res) { res->vtype= VT_LONG; res->num= (long)new idclist_t; return eOk; } const char idcargs_dellist[4]= { VT_LONG, 0 }; error_t idaapi idc_dellist(value_t *argv,value_t *res) { if (argv[0].vtype!=VT_LONG) { msg("idcext del: arg0=%d!=long\n", argv[0].vtype); return -1; } if (argv[1].vtype!=0) { msg("idcext del: too many args:%d %08lx\n", argv[1].vtype, argv[1].num); //return -1; } idclist_t *l= (idclist_t *)argv[0].num; delete l; return eOk; } const char idcargs_getlist[4]= { VT_STR, VT_WILD, 0 }; error_t idaapi idc_getlist(value_t *argv,value_t *res) { idclist_t *l = new idclist_t; if (argv[0].vtype!=VT_STR) { msg("idcext get: arg0=%d!=str\n", argv[0].vtype); return -1; } if (argv[1].vtype!=0) { msg("idcext get: too many args:%d %08lx\n", argv[1].vtype, argv[1].num); //return -1; } ListTypeMap::iterator lt= listtypes.find(argv[0]); if (lt==lt.end()) { msg("idcext get: unknown type %s\n", argv[0]); return -1; } if (!(*lt).second->(l, argv+1)) return -1; res->vtype= VT_LONG; res->num= (long)l; return eOk; } void convert_to_value_t(const value_type& v, value_t *pvt) { pvt->vtype= v.type; if (pvt->vtype==VT_STR) pvt->str= qstrdup(v.str.c_str()); else pvt->num= v.num; } void convert_to_value_type(value_t *pvt, value_type& v) { v.type= pvt->vtype; if (pvt->vtype==VT_STR) v.str= pvt->str; else v.num= pvt->num; } const char idcargs_push[4]= { VT_LONG, VT_WILD, 0 }; error_t idaapi idc_push(value_t *argv,value_t *res) { if (argv[0].vtype!=VT_LONG) { msg("idcext push: arg0=%d!=long\n", argv[0].vtype); return -1; } if (argv[1].vtype==0) { msg("idcext push: arg1 missing\n"); return -1; } idclist_t *l= (idclist_t *)argv[0].num; value_type val; convert_to_value_type(&argv[1], val); l->push_back(val); return eOk; } const char idcargs_pop[4]= { VT_LONG, 0 }; error_t idaapi idc_pop(value_t *argv,value_t *res) { if (argv[0].vtype!=VT_LONG) { msg("idcext pop: arg0=%d!=long\n", argv[0].vtype); return -1; } if (argv[1].vtype!=0) { msg("idcext pop: too many args: %d\n", argv[1].vtype); //return -1; } idclist_t *l= (idclist_t *)argv[0].num; if (l->empty()) { msg("idcext pop: empty list\n"); return -1; } convert_to_value_t(l->back(), res); l->pop_back(); return eOk; } error_t idaapi list_iter(value_t *argv,value_t *res, bool bFilter, bool bReturnList) { if (argv[0].vtype!=VT_STR) { msg("idcext - arg0=%d!=str\n", argv[0].vtype); return -1; } if (argv[1].vtype!=VT_LONG) { msg("idcext - arg1=%d!=long\n", argv[1].vtype); return -1; } if (argv[2].vtype) { msg("idcext - more than 2 args\n"); return -1; } idclist_t *l_in= (idclist_t *)argv[1].num; idclist_t *l_out= bReturnList ? new idclist_t : NULL; std::string name= str(boost::format("expr_%08lx") % (long)&name); std::string line= str(boost::format("static %s(x) { %s; return x; }") % name % argv[0].str); char errormsg[256]; if (!CompileLine(line.c_str(), errormsg, 256, NULL)) { msg("idcext - compile: %s\n", errormsg); return -1; } for (idclist_t::iterator i= l_in->begin() ; i!=l_in->end() ; ++i) { value_t map_in; value_t map_out; convert_to_value_t(*i, &map_in); if (!Run(name.c_str(), 1, &map_in, &map_out, errormsg, 256)) { msg("idcext - run: %s\n", errormsg); return -1; } if (l_out) { if (bFilter) { if (VarNum(&map_out) && map_out.num) l_out->push_back(*i); } else { value_type val; convert_to_value_type(&map_out, val); l_out->push_back(val); } } VarFree(&map_out); } if (l_out) { res->vtype= VT_LONG; res->num= (long)l_out; } return eOk; } const char idcargs_map[4]= { VT_STR, VT_LONG, 0 }; error_t idaapi idc_map(value_t *argv,value_t *res) { return list_iter(argv, res, false, true); } const char idcargs_grep[4]= { VT_STR, VT_LONG, 0 }; error_t idaapi idc_grep(value_t *argv,value_t *res) { return list_iter(argv, res, true, true); } const char idcargs_foreach[4]= { VT_STR, VT_LONG, 0 }; error_t idaapi idc_foreach(value_t *argv,value_t *res) { return list_iter(argv, res, false, false); }