mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-23 13:19:54 +00:00
* Added r_parse plugin for mandingo's mreplace
This commit is contained in:
parent
801ed768fc
commit
1d5162d8e3
@ -7,6 +7,8 @@
|
||||
#include <list.h>
|
||||
|
||||
|
||||
#define R_PARSE_STRLEN 256
|
||||
|
||||
struct r_parse_t {
|
||||
void *user;
|
||||
struct r_parse_handle_t *cur;
|
||||
|
@ -1,6 +1,8 @@
|
||||
CFLAGS=-I../../include -I../arch/ -I../arch/include -Wall -fPIC -shared -Wl,-R..
|
||||
|
||||
all: parse_dummy.so parse_x86_pseudo.so
|
||||
OBJ_MREPLACE=mreplace/mreplace.o mreplace/mmemory.o
|
||||
|
||||
all: parse_dummy.so parse_x86_pseudo.so parse_mreplace.so
|
||||
@true
|
||||
|
||||
parse_dummy.so:
|
||||
@ -11,5 +13,9 @@ parse_x86_pseudo.so: parse_x86_pseudo.o
|
||||
${CC} ${CFLAGS} -o parse_x86_pseudo.so parse_x86_pseudo.o
|
||||
@#strip -s parse_x86_pseudo.so
|
||||
|
||||
parse_mreplace.so: parse_mreplace.o ${OBJ_MREPLACE}
|
||||
${CC} ${CFLAGS} -o parse_mreplace.so parse_mreplace.o ${OBJ_MREPLACE}
|
||||
@#strip -s parse_mreplace.so
|
||||
|
||||
clean:
|
||||
-rm -f *.so *.o
|
||||
-rm -f *.so *.o ${OBJ_MREPLACE}
|
||||
|
114
libr/parse/p/mreplace/mmemory.c
Normal file
114
libr/parse/p/mreplace/mmemory.c
Normal file
@ -0,0 +1,114 @@
|
||||
//
|
||||
// Library: Memory Manage Module v1.10, Copyleft, 2009-02-25
|
||||
// Author : Mandingo, mandingo [ at ]yoire.com
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#include "mmemory.h"
|
||||
|
||||
memInfo *mInfo;
|
||||
|
||||
void memStringRealloc(memChunk *chunk){
|
||||
memCheckState();
|
||||
memChunk *temp;
|
||||
temp=memString(chunk->address);
|
||||
//printf("Reallocating chunk size %d to size %d\n",chunk->size,temp->size);
|
||||
memCopy(chunk,temp);
|
||||
memFree(temp);
|
||||
}
|
||||
|
||||
void memFree(memChunk *chunk){
|
||||
memCheckState();
|
||||
if(chunk && chunk->address){
|
||||
mInfo->allocated-=chunk->size;
|
||||
free(chunk->address);
|
||||
free(chunk);
|
||||
}
|
||||
}
|
||||
void memInit(){
|
||||
mInfo=(memInfo*)malloc(sizeof(memInfo));
|
||||
bzero(mInfo,sizeof(memInfo));
|
||||
mInfo->state=MEM_STATE_OK;
|
||||
mInfo->allocated+=sizeof(memInfo);
|
||||
}
|
||||
void memCheckState(){
|
||||
if(mInfo==NULL) memInit();
|
||||
if(mInfo->state!=MEM_STATE_OK){
|
||||
fprintf(stderr,"\rMMemmory not initialized :p\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
memInfo *memInformation(){
|
||||
memCheckState();
|
||||
return mInfo;
|
||||
}
|
||||
long memAllocated(){
|
||||
memCheckState();
|
||||
return mInfo->allocated;
|
||||
}
|
||||
memChunk *memReserve(long size){
|
||||
static memChunk *buffer;
|
||||
memCheckState();
|
||||
buffer=(memChunk*)malloc(sizeof(memChunk));
|
||||
if((buffer->address=(char*)malloc(size))==NULL){
|
||||
perror("memReserve");
|
||||
exit(0);
|
||||
}
|
||||
//printf("- reservando %d bytes\n",size);
|
||||
buffer->size=size;
|
||||
bzero(buffer->address,buffer->size);
|
||||
mInfo->allocated+=size;
|
||||
return buffer;
|
||||
}
|
||||
memChunk *memStringReserve(char *string,long nbytes){
|
||||
static memChunk *buffer;
|
||||
buffer=memReserve(nbytes);
|
||||
memCopy(buffer,memString(string));
|
||||
return buffer;
|
||||
}
|
||||
memChunk *memString(char *string){
|
||||
static memChunk *buffer;
|
||||
memCheckState();
|
||||
buffer=memReserve(strlen(string)+1);
|
||||
#if USE_BCOPY
|
||||
bcopy(string,buffer->address,strlen(string));
|
||||
#else
|
||||
memcpy(buffer->address,string,strlen(string));
|
||||
#endif
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void memCopy(memChunk *dest,memChunk *source){
|
||||
long nbytes;
|
||||
if(!dest->address){
|
||||
dest=memString(source->address);
|
||||
}else{
|
||||
nbytes=dest->size > source->size ? source->size : dest->size;
|
||||
memCheckState();
|
||||
//printf("Copying %d bytes to dest (size %d)\n",nbytes,dest->address,dest->size);
|
||||
#if USE_BCOPY
|
||||
bcopy(source->address,dest->address,nbytes);
|
||||
#else
|
||||
memcpy(dest->address,source->address,nbytes);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void memStrCat(memChunk *dest,char *string){
|
||||
long nbytes;
|
||||
memChunk result,*temp;
|
||||
|
||||
temp = memReserve(dest->size+strlen(string)+1);
|
||||
|
||||
result.address = dest->address+strlen(dest->address);
|
||||
result.size = dest->size-strlen(dest->address)+1;
|
||||
|
||||
memCopy(temp,memString(string));
|
||||
memCopy(&result,temp);
|
||||
|
||||
memFree(temp);
|
||||
}
|
32
libr/parse/p/mreplace/mmemory.h
Normal file
32
libr/parse/p/mreplace/mmemory.h
Normal file
@ -0,0 +1,32 @@
|
||||
//
|
||||
// Library: Memory Manage Module v1.10, Copyleft, 2009-02-25
|
||||
// Author : Mandingo, mandingo [ at ]yoire.com
|
||||
//
|
||||
|
||||
#define USE_BCOPY 1
|
||||
|
||||
#define MEM_STATE_BAD 0
|
||||
#define MEM_STATE_OK 1
|
||||
|
||||
typedef struct {
|
||||
char *address;
|
||||
long size;
|
||||
} memChunk;
|
||||
|
||||
typedef struct {
|
||||
long allocated;
|
||||
char state;
|
||||
} memInfo;
|
||||
|
||||
memChunk *memReserve(long size);
|
||||
void memCopy(memChunk *dest,memChunk *source);
|
||||
void memStrCat(memChunk *dest,char *string);
|
||||
memInfo *memInformation();
|
||||
long memAllocated();
|
||||
void memFree(memChunk *chunk);
|
||||
void memCheckState();
|
||||
|
||||
memChunk *memString(char *string);
|
||||
void memStringRealloc(memChunk *chunk);
|
||||
memChunk *memStringReserve(char *string,long nbytes);
|
||||
|
252
libr/parse/p/mreplace/mreplace.c
Normal file
252
libr/parse/p/mreplace/mreplace.c
Normal file
@ -0,0 +1,252 @@
|
||||
//
|
||||
// Library: Experimental PERL alike "search & replace", Copyleft, 2009-02-20
|
||||
// Author : Mandingo, mandingo [ at ]yoire.com
|
||||
//
|
||||
|
||||
#include <regex.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "mmemory.h"
|
||||
#include "mreplace.h"
|
||||
|
||||
#if !defined DEBUG2
|
||||
#define DEBUG2 0
|
||||
#endif
|
||||
|
||||
#if defined LIB
|
||||
#include "m2c_api20.h"
|
||||
#else
|
||||
#define DBG(func,...) "";
|
||||
#endif
|
||||
|
||||
#define CHECKS_CHUNCK_SIZE 1024
|
||||
#define CHECKS_CHUNCK_COUNT 6
|
||||
|
||||
int matchs(const char *string, char *pattern)
|
||||
{
|
||||
int status;
|
||||
regex_t re;
|
||||
|
||||
if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB) != 0) return(0);
|
||||
status = regexec(&re, string, (size_t) 0, NULL, 0);
|
||||
regfree(&re);
|
||||
if (status != 0) return(0);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
void sreplace(char *s,char *orig,char *rep,char multi,long dsize){
|
||||
char *p;
|
||||
memChunk *buffer,*string,*result;
|
||||
|
||||
if(!(p=strstr(s, orig))) return;
|
||||
|
||||
buffer=memReserve(dsize);
|
||||
string=memString(s);
|
||||
|
||||
memCopy(buffer, string);
|
||||
|
||||
snprintf(buffer->address+(p-s), buffer->size-(p-s),"%s%s", rep, p+strlen(orig));
|
||||
|
||||
result=memString(buffer->address);
|
||||
|
||||
strcpy(s,result->address); //unsafe
|
||||
|
||||
memFree(string);
|
||||
memFree(result);
|
||||
memFree(buffer);
|
||||
}
|
||||
|
||||
char *mreplace(char *string, char *se,char *rep)
|
||||
{
|
||||
int status,m,i;
|
||||
char *s;
|
||||
regex_t re;
|
||||
size_t nmatch = 16;
|
||||
regmatch_t pm[nmatch];
|
||||
char regError[64],*p;
|
||||
ulong offset = 0;
|
||||
char field[16];
|
||||
char *sData;
|
||||
memChunk *result,*temp,*found,*ffound;
|
||||
char *search;
|
||||
|
||||
if(!string) return "";
|
||||
if(!strlen(se)) return string;
|
||||
if(!strcmp(se,rep)) return string;
|
||||
|
||||
temp=memStringReserve(string,INPUTLINE_BUFFER_REPLACE_SIZE);
|
||||
|
||||
#if DEBUG2
|
||||
sData=strdup(string);
|
||||
DBG("mreplace(string,se,re)","string : %s",sData);
|
||||
DBG("mreplace(string,se,re)","search : %s",se);
|
||||
DBG("mreplace(string,se,re)","replace : %s",replace);
|
||||
#endif
|
||||
|
||||
p=(char*)string;
|
||||
search=strdup(se);
|
||||
|
||||
if(matchs(search,"\\d")) sreplace(search,"\\d","[0-9]\0",1,6);
|
||||
|
||||
if(regcomp(&re, search, REG_EXTENDED) != 0) if(regcomp(&re, search, REG_EXTENDED<<1)) return (char*)string;
|
||||
if(status = regexec(&re, string, nmatch, pm, 0)) return (char*)string;
|
||||
found = memReserve(INPUTLINE_BUFFER_REPLACE_SIZE);
|
||||
ffound = memReserve(INPUTLINE_BUFFER_REPLACE_SIZE);
|
||||
while(!status){
|
||||
offset=strlen(temp->address)-strlen(string);
|
||||
snprintf(found->address,INPUTLINE_BUFFER_REPLACE_SIZE,"%.*s",pm[0].rm_eo - pm[0].rm_so, &string[pm[0].rm_so],&string[pm[0].rm_so]);
|
||||
#if DEBUG2
|
||||
printf("------->> found \"%s\" length => %d offset[%d]\n",
|
||||
found->address,
|
||||
strlen(temp),offset);
|
||||
#endif
|
||||
sreplace(temp->address+offset,found->address,rep,0,INPUTLINE_BUFFER_REPLACE_SIZE-offset);
|
||||
for(i=1;i<nmatch;i++){
|
||||
snprintf(ffound->address,INPUTLINE_BUFFER_REPLACE_SIZE,"%.*s",pm[i].rm_eo - pm[i].rm_so, &string[pm[i].rm_so],&string[pm[i].rm_so]);
|
||||
snprintf(field,sizeof(field),"\\%d",i);
|
||||
if(strlen(ffound->address)) {
|
||||
sreplace(temp->address,field,ffound->address,1,INPUTLINE_BUFFER_REPLACE_SIZE);
|
||||
}else{
|
||||
sreplace(temp->address,field,"",1,INPUTLINE_BUFFER_REPLACE_SIZE);
|
||||
continue;
|
||||
}
|
||||
#if DEBUG2
|
||||
printf(">> subfound %2d '%s' => '%s' length %d\n",
|
||||
i,
|
||||
ffound->address,
|
||||
temp->address,offset);
|
||||
#endif
|
||||
}
|
||||
if(offset<0) offset=-offset;
|
||||
if(*string && strlen(string+pm[0].rm_eo)) {
|
||||
string+=pm[0].rm_eo;
|
||||
status = regexec(&re, string, nmatch, pm, 0);
|
||||
}else{
|
||||
status=-1;
|
||||
}
|
||||
}
|
||||
#if DEBUG2
|
||||
DBG("mreplace(string,se,re)","result : %s",temp->address);
|
||||
#endif
|
||||
memFree(found);
|
||||
memFree(ffound);
|
||||
result=memString(temp->address);
|
||||
memFree(temp);
|
||||
return result->address;
|
||||
}
|
||||
|
||||
char *treplace(char *data,char *search,char *replace){
|
||||
long offset=0,f;
|
||||
char line[INPUTLINE_BUFFER_REPLACE_SIZE],*newline,*p;
|
||||
|
||||
memChunk *result;
|
||||
ulong resultAllocSize;
|
||||
|
||||
#if DEBUG2
|
||||
DBG("treplace(string,se,re)","string : %s",data);
|
||||
DBG("treplace(string,se,re)","search : %s",search);
|
||||
DBG("treplace(string,se,re)","replace : %s",replace);
|
||||
#endif
|
||||
|
||||
if(!strlen(data)) return data;
|
||||
if(!strlen(search)) return data;
|
||||
|
||||
//memFree(result);
|
||||
result=memReserve(INPUTLINE_BUFFER_REPLACE_SIZE);
|
||||
|
||||
p=data;
|
||||
while(sscanf(p,"%[^\n]",line)==1){
|
||||
if(p-data>strlen(data)) break;
|
||||
newline=mreplace(line,search,replace);
|
||||
|
||||
memStrCat(result,newline);
|
||||
if(*(p+strlen(line))) memStrCat(result,"\n");else break;
|
||||
|
||||
p+=strlen(line)+1;
|
||||
}
|
||||
memStringRealloc(result);
|
||||
return result->address;
|
||||
}
|
||||
|
||||
void doChecks(){
|
||||
char *checkBuffer,*checkresult,*sIn;
|
||||
long i,n,total,invalid=0;
|
||||
typedef struct {char *in,*s,*r,*out;} sCheck;
|
||||
sCheck checks[]={
|
||||
{"{{div.cOptions}}go {{tag.tag56}} {{get.link.parent.html}}/ edit {{tag.tag57}} / edit {{tag.tag58}} / rename {{tag.tag59}} / move {{tag.tag60}} / add {{tag.tag61}}{{get.delete.html}} / {{get.link.login.html}}{{enddiv}}", ".*(\\{\\{\\w+\\.\\w+(\\.\\w+)?\\}\\}).*","\\1","{{get.delete.html}}"},
|
||||
{"abracadabra", "a", "b", "bbrbcbdbbrb"},
|
||||
{"a1a2a3a4a5a", "\\d", "_", "a_a_a_a_a_a"},
|
||||
{"z1b4a5a", "(\\w)", "[\\1]", "[z][1][b][4][a][5][a]"},
|
||||
{"farooeboar", "(.)..(..).(.).", "\\1\\2\\3", "foobar"},
|
||||
{"file.c", "(([^\\.]+)\\.(.+))", "[\\1] name=\\2 ext=\\3", "[file.c] name=file ext=c"},
|
||||
{"helloworld", "([e-o])", "_\\1_", "_h__e__l__l__o_w_o_r_l_d"},
|
||||
{"I' a {{get.tag}}",".*(\\{\\{\\w+\\.\\w+(\\.\\w+)?\\}\\}).*","found tag \"\\1\"","found tag \"{{get.tag}}\""},
|
||||
{"get.param","(\\w+?)\\..+","method is \"\\1\"","method is \"get\""},
|
||||
{"get.param","[^\\.]+\\.([^\\.]+).*","tagname is \"\\1\"","tagname is \"param\""}
|
||||
};
|
||||
total=sizeof(checks)/sizeof(checks[0])-1;
|
||||
|
||||
if((checkBuffer=(char*)malloc(CHECKS_CHUNCK_COUNT*CHECKS_CHUNCK_SIZE))==NULL){
|
||||
perror("malloc");
|
||||
}else{
|
||||
memset(checkBuffer,0,CHECKS_CHUNCK_COUNT*CHECKS_CHUNCK_SIZE);
|
||||
}
|
||||
|
||||
fprintf(stdout," [+] Performing several replacements to check consistence ");
|
||||
for(n=0;n<100;n++){
|
||||
if(!(n%25)){
|
||||
printf(".");
|
||||
fflush(stdout);
|
||||
}
|
||||
for(i=0;i<total;i++){
|
||||
checkresult=treplace(checks[i].in,checks[i].s,checks[i].r);
|
||||
sIn=strdup(checks[i].in);
|
||||
if(strlen(sIn)>20) memcpy(sIn+15," ...\0",5);
|
||||
if(strcmp(checkresult,checks[i].out)){
|
||||
fprintf(stderr,"\r[%d/%d] %-20s s: %-30s r: %-20s => %-25s ",i+1,total,sIn,checks[i].s,checks[i].r,checkresult);
|
||||
fprintf(stdout," ERR :(\n");
|
||||
exit(0);
|
||||
}else{
|
||||
if(!n){
|
||||
fprintf(stderr,"\r[%d/%d] %-20s s: %-30s r: %-20s => %-25s ",i+1,total,sIn,checks[i].s,checks[i].r,checkresult);
|
||||
fprintf(stdout," OK :)\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(n=1;n<=CHECKS_CHUNCK_COUNT;n+=1+CHECKS_CHUNCK_COUNT/10){
|
||||
fprintf(stdout,"\r[ + ] Checking stability for different input sizes consistence %d bytes, memory allocated: %d bytes",n*CHECKS_CHUNCK_COUNT*CHECKS_CHUNCK_SIZE,memAllocated());
|
||||
fflush(stdout);
|
||||
memset(checkBuffer,'.',n*CHECKS_CHUNCK_SIZE-1);
|
||||
checkBuffer[n*CHECKS_CHUNCK_SIZE]=0;
|
||||
mreplace(checkBuffer,"\\.","_");
|
||||
treplace(checkBuffer,"_",".");
|
||||
}
|
||||
fprintf(stdout,"\n");
|
||||
fprintf(stdout,"[ m ] Memory allocated final: %d bytes\n",memAllocated());
|
||||
}
|
||||
#if !defined LIB
|
||||
/*
|
||||
builds a binary for command line "search & replace" tests
|
||||
*/
|
||||
int main(char argc,char **argv){
|
||||
if(argc==4 && strlen(argv[2])){
|
||||
#if DEBUG2
|
||||
printf("Input string: %s, length %d, search %s, replace %s\n",argv[1],strlen(argv[1]),argv[2],argv[3]);
|
||||
#endif
|
||||
fprintf(stdout,"%s\n",treplace(argv[1],argv[2],argv[3]));
|
||||
}else{
|
||||
fprintf(stdout, "Perl alike \"search & replace\" v1.01 by Mandingo, Copyleft, 2009\n");
|
||||
doChecks();
|
||||
fprintf(stdout, "Usage: %s \"<text>\" \"<search>\" \"<replace>\"\n",argv[0]);
|
||||
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
17
libr/parse/p/mreplace/mreplace.h
Normal file
17
libr/parse/p/mreplace/mreplace.h
Normal file
@ -0,0 +1,17 @@
|
||||
//
|
||||
// Library: Experimental PERL alike "search & replace", Copyleft, 2009-02-20
|
||||
// Author : Mandingo, mandingo [ at ]yoire.com
|
||||
//
|
||||
|
||||
|
||||
#if !defined INPUTLINE_BUFFER_REPLACE_SIZE
|
||||
#define INPUTLINE_BUFFER_REPLACE_SIZE 32768
|
||||
#endif
|
||||
|
||||
//search & replace strings - no regexp
|
||||
extern void sreplace(char *s,char *orig,char *rep,char multi,long dsize);
|
||||
|
||||
//search & replace strings - regexp + multiline safe
|
||||
extern char *treplace(char *string,char *search,char *replace);
|
||||
|
||||
extern char *mreplace(char *string, char *se,char *replace);
|
44
libr/parse/p/parse_mreplace.c
Normal file
44
libr/parse/p/parse_mreplace.c
Normal file
@ -0,0 +1,44 @@
|
||||
/* radare - LGPL - Copyright 2009 nibble<.ds@gmail.com> */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mreplace/mreplace.h"
|
||||
|
||||
#include <r_types.h>
|
||||
#include <r_lib.h>
|
||||
#include <r_util.h>
|
||||
#include <r_parse.h>
|
||||
|
||||
|
||||
struct mreplace_t {
|
||||
char *data;
|
||||
char *search;
|
||||
char *replace;
|
||||
};
|
||||
|
||||
static int parse(struct r_parse_t *p, void *data, char *str)
|
||||
{
|
||||
struct mreplace_t *sdata = (struct mreplace_t*)data;
|
||||
char *buf = NULL;
|
||||
buf = treplace(sdata->data, sdata->search, sdata->replace);
|
||||
memcpy(str, buf, R_PARSE_STRLEN);
|
||||
if (buf != NULL)
|
||||
free(buf);
|
||||
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
static struct r_parse_handle_t r_parse_plugin_parse_mreplace = {
|
||||
.name = "parse_mreplace",
|
||||
.desc = "mreplace parsing plugin",
|
||||
.init = NULL,
|
||||
.fini = NULL,
|
||||
.parse = &parse,
|
||||
};
|
||||
|
||||
struct r_lib_struct_t radare_plugin = {
|
||||
.type = R_LIB_TYPE_PARSE,
|
||||
.data = &r_parse_plugin_parse_mreplace
|
||||
};
|
Loading…
Reference in New Issue
Block a user