1 /* ctsw.h -- call-/swaptrick filter
2
3 This file is part of the UPX executable compressor.
4
5 Copyright (C) 1996-2020 Markus Franz Xaver Johannes Oberhumer
6 Copyright (C) 1996-2020 Laszlo Molnar
7 All Rights Reserved.
8
9 UPX and the UCL library are free software; you can redistribute them
10 and/or modify them under the terms of the GNU General Public License as
11 published by the Free Software Foundation; either version 2 of
12 the License, or (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; see the file COPYING.
21 If not, write to the Free Software Foundation, Inc.,
22 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23
24 Markus F.X.J. Oberhumer Laszlo Molnar
25 <markus@oberhumer.com> <ezerotven+github@gmail.com>
26 */
27
28
29
30 /*************************************************************************
31 // 16-bit call-/swaptrick ("naive")
32 **************************************************************************/
33
34 #define CTSW16(f, cond1, cond2, addvalue, get, set) \
35 upx_byte *b = f->buf; \
36 upx_byte *b_end = b + f->buf_len - 3; \
37 do { \
38 if (cond1) \
39 { \
40 b += 1; \
41 unsigned a = (unsigned) (b - f->buf); \
42 f->lastcall = a; \
43 set(b, get(b) + (addvalue)); \
44 f->calls++; \
45 b += 2 - 1; \
46 } \
47 else if (cond2) \
48 { \
49 b += 1; \
50 unsigned a = (unsigned) (b - f->buf); \
51 f->lastcall = a; \
52 set(b, get(b)); \
53 f->calls++; \
54 b += 2 - 1; \
55 } \
56 } while (++b < b_end); \
57 if (f->lastcall) f->lastcall += 2; \
58 return 0;
59
60
61 // filter
f_ctsw16_e8_e9(Filter * f)62 static int f_ctsw16_e8_e9(Filter *f)
63 {
64 CTSW16(f, (*b == 0xe8), (*b == 0xe9), a + f->addvalue, get_le16, set_be16)
65 }
66
f_ctsw16_e9_e8(Filter * f)67 static int f_ctsw16_e9_e8(Filter *f)
68 {
69 CTSW16(f, (*b == 0xe9), (*b == 0xe8), a + f->addvalue, get_le16, set_be16)
70 }
71
72
73 // unfilter
u_ctsw16_e8_e9(Filter * f)74 static int u_ctsw16_e8_e9(Filter *f)
75 {
76 CTSW16(f, (*b == 0xe8), (*b == 0xe9), 0 - a - f->addvalue, get_be16, set_le16)
77 }
78
u_ctsw16_e9_e8(Filter * f)79 static int u_ctsw16_e9_e8(Filter *f)
80 {
81 CTSW16(f, (*b == 0xe9), (*b == 0xe8), 0 - a - f->addvalue, get_be16, set_le16)
82 }
83
84
85 // scan
s_ctsw16_e8_e9(Filter * f)86 static int s_ctsw16_e8_e9(Filter *f)
87 {
88 CTSW16(f, (*b == 0xe8), (*b == 0xe9), a + f->addvalue, get_le16, set_dummy)
89 }
90
s_ctsw16_e9_e8(Filter * f)91 static int s_ctsw16_e9_e8(Filter *f)
92 {
93 CTSW16(f, (*b == 0xe9), (*b == 0xe8), a + f->addvalue, get_le16, set_dummy)
94 }
95
96
97 #undef CTSW16
98
99
100 /*************************************************************************
101 // 32-bit call-/swaptrick ("naive")
102 **************************************************************************/
103
104 #define CTSW32(f, cond1, cond2, addvalue, get, set) \
105 upx_byte *b = f->buf; \
106 upx_byte *b_end = b + f->buf_len - 5; \
107 do { \
108 if (cond1) \
109 { \
110 b += 1; \
111 unsigned a = (unsigned) (b - f->buf); \
112 f->lastcall = a; \
113 set(b, get(b) + (addvalue)); \
114 f->calls++; \
115 b += 4 - 1; \
116 } \
117 else if (cond2) \
118 { \
119 b += 1; \
120 unsigned a = (unsigned) (b - f->buf); \
121 f->lastcall = a; \
122 set(b, get(b)); \
123 f->calls++; \
124 b += 4 - 1; \
125 } \
126 } while (++b < b_end); \
127 if (f->lastcall) f->lastcall += 4; \
128 return 0;
129
130
131 // filter
f_ctsw32_e8_e9(Filter * f)132 static int f_ctsw32_e8_e9(Filter *f)
133 {
134 CTSW32(f, (*b == 0xe8), (*b == 0xe9), a + f->addvalue, get_le32, set_be32)
135 }
136
f_ctsw32_e9_e8(Filter * f)137 static int f_ctsw32_e9_e8(Filter *f)
138 {
139 CTSW32(f, (*b == 0xe9), (*b == 0xe8), a + f->addvalue, get_le32, set_be32)
140 }
141
142
143 // unfilter
u_ctsw32_e8_e9(Filter * f)144 static int u_ctsw32_e8_e9(Filter *f)
145 {
146 CTSW32(f, (*b == 0xe8), (*b == 0xe9), 0 - a - f->addvalue, get_be32, set_le32)
147 }
148
u_ctsw32_e9_e8(Filter * f)149 static int u_ctsw32_e9_e8(Filter *f)
150 {
151 CTSW32(f, (*b == 0xe9), (*b == 0xe8), 0 - a - f->addvalue, get_be32, set_le32)
152 }
153
154
155 // scan
s_ctsw32_e8_e9(Filter * f)156 static int s_ctsw32_e8_e9(Filter *f)
157 {
158 CTSW32(f, (*b == 0xe8), (*b == 0xe9), a + f->addvalue, get_le32, set_dummy)
159 }
160
s_ctsw32_e9_e8(Filter * f)161 static int s_ctsw32_e9_e8(Filter *f)
162 {
163 CTSW32(f, (*b == 0xe9), (*b == 0xe8), a + f->addvalue, get_le32, set_dummy)
164 }
165
166
167 #undef CTSW32
168
169 /* vim:set ts=4 sw=4 et: */
170