#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
void enable_code(void *addr) {
long pagesize = sysconf(_SC_PAGESIZE);
char* p = (void*)(((int) addr ) & ~(pagesize-1));
if(mprotect(p, pagesize, PROT_READ | PROT_WRITE | PROT_EXEC)) {
fprintf(stderr, "mprotect(2) failed. errno = %d?n", errno);
exit(1);
}
}
void prt1(char *str) {
printf("1:%s\n",str);
}
void prt2(char *str) {
printf("2:%s\n",str);
}
void*
make_caller_with_void_ptr(void* prog, void *strp) {
unsigned char opcodes[] = {
0x55, /* push %ebp */
0x89,0xe5, /* mov %esp,%ebp */
0x53, /* push %ebx */
0x83,0xec,0x04, /* sub $0x4,%esp */
0xb8,0,0,0,0, /* movl $0x0,%eax */
0x89,0x04,0x24, /* mov %eax,(%esp) */
0xb8,0,0,0,0, /* movl $0x0,%eax */
0xff,0xd0, /* call *%eax */
0x83,0xc4,0x04, /* add $0x4,%esp */
0x5b, /* pop %ebx */
0x5d, /* pop %ebp */
0xc3 /* ret */
};
static const int offset_string = 8;
static const int offset_callee = 16;
void(*code)(void);
code = malloc(sizeof(opcodes));
memcpy(code, opcodes, sizeof(opcodes));
memcpy(code+offset_string, &strp, sizeof(&strp));
memcpy(code+offset_callee, &prog, sizeof(&prog));
enable_code(code);
return code;
}
int main(int argc, char* argv[]) {
void(*code1)(void);
void(*code2)(void);
code1 = make_caller_with_void_ptr(prt1, "this is code1");
code2 = make_caller_with_void_ptr(prt2, "this is code2");
printf("code1:");
code1();
printf("code2:");
code2();
exit(0);
}
Posted by minemaz at 2010年03月15日 01:53
すみません.こういうのとはやりたいことは全然違いますか?(COBOLでの対応は全然わかりませんけど)
http://d.hatena.ne.jp/elf/20100126/1264500332
どっちかというと
#!/usr/bin/perl -w
sub ptr1 { print @_; }
my $addr = \&ptr1;
my $strp = "this is code1";
my $code1 = sub {&$addr($strp);};
&$code1();
こんな感じのことをやりたいな-とか。
もちろん、ptr1みたいな単純な処理じゃなくてですね。