1 | Perl scripts for assembler sources
|
---|
2 | ==================================
|
---|
3 |
|
---|
4 | The perl scripts in this directory are my 'hack' to generate
|
---|
5 | multiple different assembler formats via the one original script.
|
---|
6 |
|
---|
7 | The way to use this library is to start with adding the path to this directory
|
---|
8 | and then include it.
|
---|
9 |
|
---|
10 | push(@INC,"perlasm","../../perlasm");
|
---|
11 | require "x86asm.pl";
|
---|
12 |
|
---|
13 | The first thing we do is setup the file and type of assembler
|
---|
14 |
|
---|
15 | &asm_init($ARGV[0]);
|
---|
16 |
|
---|
17 | The first argument is the 'type'. Currently
|
---|
18 | `cpp`, `sol`, `a.out`, `elf` or `win32`.
|
---|
19 | The second argument is the file name.
|
---|
20 |
|
---|
21 | The reciprocal function is
|
---|
22 | `&asm_finish()` which should be called at the end.
|
---|
23 |
|
---|
24 | There are two main 'packages'. `x86ms.pl`, which is the Microsoft assembler,
|
---|
25 | and `x86unix.pl` which is the unix (gas) version.
|
---|
26 |
|
---|
27 | Functions of interest are:
|
---|
28 |
|
---|
29 | &external_label("des_SPtrans"); declare and external variable
|
---|
30 | &LB(reg); Low byte for a register
|
---|
31 | &HB(reg); High byte for a register
|
---|
32 | &BP(off,base,index,scale) Byte pointer addressing
|
---|
33 | &DWP(off,base,index,scale) Word pointer addressing
|
---|
34 | &stack_push(num) Basically a 'sub esp, num*4' with extra
|
---|
35 | &stack_pop(num) inverse of stack_push
|
---|
36 | &function_begin(name,extra) Start a function with pushing of
|
---|
37 | edi, esi, ebx and ebp. extra is extra win32
|
---|
38 | external info that may be required.
|
---|
39 | &function_begin_B(name,extra) Same as normal function_begin but no
|
---|
40 | pushing.
|
---|
41 | &function_end(name) Call at end of function.
|
---|
42 | &function_end_A(name) Standard pop and ret, for use inside
|
---|
43 | functions.
|
---|
44 | &function_end_B(name) Call at end but with pop or ret.
|
---|
45 | &swtmp(num) Address on stack temp word.
|
---|
46 | &wparam(num) Parameter number num, that was push in
|
---|
47 | C convention. This all works over pushes
|
---|
48 | and pops.
|
---|
49 | &comment("hello there") Put in a comment.
|
---|
50 | &label("loop") Refer to a label, normally a jmp target.
|
---|
51 | &set_label("loop") Set a label at this point.
|
---|
52 | &data_word(word) Put in a word of data.
|
---|
53 |
|
---|
54 | So how does this all hold together? Given
|
---|
55 |
|
---|
56 | int calc(int len, int *data)
|
---|
57 | {
|
---|
58 | int i,j=0;
|
---|
59 |
|
---|
60 | for (i=0; i<len; i++)
|
---|
61 | {
|
---|
62 | j+=other(data[i]);
|
---|
63 | }
|
---|
64 | }
|
---|
65 |
|
---|
66 | So a very simple version of this function could be coded as
|
---|
67 |
|
---|
68 | push(@INC,"perlasm","../../perlasm");
|
---|
69 | require "x86asm.pl";
|
---|
70 |
|
---|
71 | &asm_init($ARGV[0]);
|
---|
72 |
|
---|
73 | &external_label("other");
|
---|
74 |
|
---|
75 | $tmp1= "eax";
|
---|
76 | $j= "edi";
|
---|
77 | $data= "esi";
|
---|
78 | $i= "ebp";
|
---|
79 |
|
---|
80 | &comment("a simple function");
|
---|
81 | &function_begin("calc");
|
---|
82 | &mov( $data, &wparam(1)); # data
|
---|
83 | &xor( $j, $j);
|
---|
84 | &xor( $i, $i);
|
---|
85 |
|
---|
86 | &set_label("loop");
|
---|
87 | &cmp( $i, &wparam(0));
|
---|
88 | &jge( &label("end"));
|
---|
89 |
|
---|
90 | &mov( $tmp1, &DWP(0,$data,$i,4));
|
---|
91 | &push( $tmp1);
|
---|
92 | &call( "other");
|
---|
93 | &add( $j, "eax");
|
---|
94 | &pop( $tmp1);
|
---|
95 | &inc( $i);
|
---|
96 | &jmp( &label("loop"));
|
---|
97 |
|
---|
98 | &set_label("end");
|
---|
99 | &mov( "eax", $j);
|
---|
100 |
|
---|
101 | &function_end("calc");
|
---|
102 |
|
---|
103 | &asm_finish();
|
---|
104 |
|
---|
105 | The above example is very very unoptimised but gives an idea of how
|
---|
106 | things work.
|
---|
107 |
|
---|
108 | There is also a cbc mode function generator in cbc.pl
|
---|
109 |
|
---|
110 | &cbc($name,
|
---|
111 | $encrypt_function_name,
|
---|
112 | $decrypt_function_name,
|
---|
113 | $true_if_byte_swap_needed,
|
---|
114 | $parameter_number_for_iv,
|
---|
115 | $parameter_number_for_encrypt_flag,
|
---|
116 | $first_parameter_to_pass,
|
---|
117 | $second_parameter_to_pass,
|
---|
118 | $third_parameter_to_pass);
|
---|
119 |
|
---|
120 | So for example, given
|
---|
121 |
|
---|
122 | void BF_encrypt(BF_LONG *data,BF_KEY *key);
|
---|
123 | void BF_decrypt(BF_LONG *data,BF_KEY *key);
|
---|
124 | void BF_cbc_encrypt(unsigned char *in, unsigned char *out, long length,
|
---|
125 | BF_KEY *ks, unsigned char *iv, int enc);
|
---|
126 |
|
---|
127 | &cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt",1,4,5,3,-1,-1);
|
---|
128 |
|
---|
129 | &cbc("des_ncbc_encrypt","des_encrypt","des_encrypt",0,4,5,3,5,-1);
|
---|
130 | &cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3",0,6,7,3,4,5);
|
---|