Skip to content

Commit 08e6e2b

Browse files
authored
Fix #23405 - Implement multibyte binary write support in the 'pb' command ##io
* Documented in radareorg/radare2-book#403 * Add multibyte pbwb test cases
1 parent de5e448 commit 08e6e2b

File tree

2 files changed

+127
-15
lines changed

2 files changed

+127
-15
lines changed

libr/core/cmd_write.inc.c

Lines changed: 66 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2214,22 +2214,73 @@ static int cmd_wa(void *data, const char *input) {
22142214

22152215
static int cmd_wb(void *data, const char *input) {
22162216
RCore *core = (RCore *)data;
2217-
ut8 b = core->block[0];
2218-
char *ui = r_str_newf ("%sb", r_str_trim_head_ro (input));
2219-
int uil = strlen (ui) - 1;
2220-
int n = r_num_get (NULL, ui);
2221-
free (ui);
2222-
if (uil > 8) {
2223-
R_LOG_ERROR ("wb only operates on bytes");
2224-
} else if (uil > 0) {
2225-
// Shift left and right to zero uil most significant bits
2226-
b <<= uil;
2227-
b >>= uil;
2228-
// Overwrite uil most significant bits and keep the rest
2229-
b |= (n << (8 - uil));
2230-
r_io_write_at (core->io, core->offset, &b, 1);
2231-
} else {
2217+
int uil = strlen (input);
2218+
char c;
2219+
int i;
2220+
2221+
// Check that user provided some input
2222+
if (uil == 0) {
22322223
r_core_cmd_help_match (core, help_msg_w, "wb");
2224+
return 0;
2225+
}
2226+
2227+
// Check that user input only contains binary data
2228+
for (i = 0; i < uil; i++) {
2229+
c = input[i];
2230+
// Ignore whitespaces
2231+
if (isspace(c)) {
2232+
continue;
2233+
}
2234+
// Check that user input only contains ones and zeros
2235+
if (c != '0' && c != '1') {
2236+
R_LOG_ERROR ("wb operates only on binary data");
2237+
return 0;
2238+
}
2239+
}
2240+
2241+
// Iterate user input bitwise and write output every 8 bits
2242+
int bits_read = 0;
2243+
int block_offset = 0;
2244+
ut8 byte = 0;
2245+
for (i = 0; i < uil; i++) {
2246+
// Read a bit
2247+
c = input[i];
2248+
2249+
// Ignore whitespaces
2250+
if (isspace(c)) {
2251+
continue;
2252+
}
2253+
2254+
if (c == '1') {
2255+
// Bits are read and bytes constructed from most to
2256+
// least significant.
2257+
byte |= (1 << (7 - bits_read));
2258+
}
2259+
bits_read++;
2260+
2261+
// Write a byte if we've read 8 bits
2262+
if (bits_read % 8 == 0) {
2263+
r_io_write_at (
2264+
core->io,
2265+
core->offset + block_offset,
2266+
&byte,
2267+
1
2268+
);
2269+
block_offset++;
2270+
bits_read = 0;
2271+
byte = 0;
2272+
}
2273+
}
2274+
2275+
// Write any possible remaining ui bits
2276+
if (bits_read != 0) {
2277+
ut8 b = core->block[block_offset];
2278+
// Shift left and right to zero bits_read most significant bits
2279+
b <<= bits_read;
2280+
b >>= bits_read;
2281+
// Overwrite bits_read most significant bits and keep the rest
2282+
b |= byte;
2283+
r_io_write_at (core->io, core->offset + block_offset, &b, 1);
22332284
}
22342285

22352286
return 0;

test/db/cmd/cmd_print_bitformat

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,64 @@ EXPECT=<<EOF
9191
01111111
9292
EOF
9393
RUN
94+
95+
NAME=pbwb two bytes
96+
FILE=-
97+
CMDS=<<EOF
98+
pb 16
99+
wb 1111111111111111
100+
pb 16
101+
wb 0 @ 1
102+
pb 16
103+
EOF
104+
EXPECT=<<EOF
105+
0000000000000000
106+
1111111111111111
107+
1111111101111111
108+
EOF
109+
RUN
110+
111+
NAME=pbwb 3.5 bytes
112+
FILE=-
113+
CMDS=<<EOF
114+
pb 28
115+
wb 1111111111111111111111111111
116+
pb 28
117+
wb 1010101010101010101010101010
118+
pb 28
119+
wb 0 @ 3
120+
pb 28
121+
EOF
122+
EXPECT=<<EOF
123+
0000000000000000000000000000
124+
1111111111111111111111111111
125+
1010101010101010101010101010
126+
1010101010101010101010100010
127+
EOF
128+
RUN
129+
130+
NAME=pbwb space
131+
FILE=-
132+
CMDS=<<EOF
133+
pb 16
134+
wb 11111111 11111111
135+
pb 16
136+
wb 0 @ 1
137+
pb 16
138+
EOF
139+
EXPECT=<<EOF
140+
0000000000000000
141+
1111111111111111
142+
1111111101111111
143+
EOF
144+
RUN
145+
146+
NAME=pbwb invalid chars
147+
FILE=-
148+
CMDS=<<EOF
149+
wb 0xff
150+
EOF
151+
EXPECT_ERR=<<EOF
152+
ERROR: wb operates only on binary data
153+
EOF
154+
RUN

0 commit comments

Comments
 (0)