1 /* sw.h -- 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 swaptrick ("naive")
32 **************************************************************************/
33
34 #define SW16(f, cond, get, set) \
35 upx_byte *b = f->buf; \
36 upx_byte *b_end = b + f->buf_len - 3; \
37 do { \
38 if (cond) \
39 { \
40 b += 1; \
41 unsigned a = (unsigned) (b - f->buf); \
42 f->lastcall = a; \
43 set(b, get(b)); \
44 f->calls++; \
45 b += 2 - 1; \
46 } \
47 } while (++b < b_end); \
48 if (f->lastcall) f->lastcall += 2; \
49 return 0;
50
51
52 // filter
f_sw16_e8(Filter * f)53 static int f_sw16_e8(Filter *f)
54 {
55 SW16(f, (*b == 0xe8), get_le16, set_be16)
56 }
57
f_sw16_e9(Filter * f)58 static int f_sw16_e9(Filter *f)
59 {
60 SW16(f, (*b == 0xe9), get_le16, set_be16)
61 }
62
f_sw16_e8e9(Filter * f)63 static int f_sw16_e8e9(Filter *f)
64 {
65 SW16(f, (*b == 0xe8 || *b == 0xe9), get_le16, set_be16)
66 }
67
68
69 // unfilter
u_sw16_e8(Filter * f)70 static int u_sw16_e8(Filter *f)
71 {
72 SW16(f, (*b == 0xe8), get_be16, set_le16)
73 }
74
u_sw16_e9(Filter * f)75 static int u_sw16_e9(Filter *f)
76 {
77 SW16(f, (*b == 0xe9), get_be16, set_le16)
78 }
79
u_sw16_e8e9(Filter * f)80 static int u_sw16_e8e9(Filter *f)
81 {
82 SW16(f, (*b == 0xe8 || *b == 0xe9), get_be16, set_le16)
83 }
84
85
86 // scan
s_sw16_e8(Filter * f)87 static int s_sw16_e8(Filter *f)
88 {
89 SW16(f, (*b == 0xe8), get_le16, set_dummy)
90 }
91
s_sw16_e9(Filter * f)92 static int s_sw16_e9(Filter *f)
93 {
94 SW16(f, (*b == 0xe9), get_le16, set_dummy)
95 }
96
s_sw16_e8e9(Filter * f)97 static int s_sw16_e8e9(Filter *f)
98 {
99 SW16(f, (*b == 0xe8 || *b == 0xe9), get_le16, set_dummy)
100 }
101
102
103 #undef SW16
104
105
106
107
108 /*************************************************************************
109 // 32-bit swaptrick ("naive")
110 **************************************************************************/
111
112 #define SW32(f, cond, get, set) \
113 upx_byte *b = f->buf; \
114 upx_byte *b_end = b + f->buf_len - 5; \
115 do { \
116 if (cond) \
117 { \
118 b += 1; \
119 unsigned a = (unsigned) (b - f->buf); \
120 f->lastcall = a; \
121 set(b, get(b)); \
122 f->calls++; \
123 b += 4 - 1; \
124 } \
125 } while (++b < b_end); \
126 if (f->lastcall) f->lastcall += 4; \
127 return 0;
128
129
130 // filter
f_sw32_e8(Filter * f)131 static int f_sw32_e8(Filter *f)
132 {
133 SW32(f, (*b == 0xe8), get_le32, set_be32)
134 }
135
f_sw32_e9(Filter * f)136 static int f_sw32_e9(Filter *f)
137 {
138 SW32(f, (*b == 0xe9), get_le32, set_be32)
139 }
140
f_sw32_e8e9(Filter * f)141 static int f_sw32_e8e9(Filter *f)
142 {
143 SW32(f, (*b == 0xe8 || *b == 0xe9), get_le32, set_be32)
144 }
145
146
147 // unfilter
u_sw32_e8(Filter * f)148 static int u_sw32_e8(Filter *f)
149 {
150 SW32(f, (*b == 0xe8), get_be32, set_le32)
151 }
152
u_sw32_e9(Filter * f)153 static int u_sw32_e9(Filter *f)
154 {
155 SW32(f, (*b == 0xe9), get_be32, set_le32)
156 }
157
u_sw32_e8e9(Filter * f)158 static int u_sw32_e8e9(Filter *f)
159 {
160 SW32(f, (*b == 0xe8 || *b == 0xe9), get_be32, set_le32)
161 }
162
163
164 // scan
s_sw32_e8(Filter * f)165 static int s_sw32_e8(Filter *f)
166 {
167 SW32(f, (*b == 0xe8), get_le32, set_dummy)
168 }
169
s_sw32_e9(Filter * f)170 static int s_sw32_e9(Filter *f)
171 {
172 SW32(f, (*b == 0xe9), get_le32, set_dummy)
173 }
174
s_sw32_e8e9(Filter * f)175 static int s_sw32_e8e9(Filter *f)
176 {
177 SW32(f, (*b == 0xe8 || *b == 0xe9), get_le32, set_dummy)
178 }
179
180
181 #undef SW32
182
183 /* vim:set ts=4 sw=4 et: */
184