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