Skip to content

Commit 8964cf5

Browse files
committed
Added AI generated tests for the strings feature.
1 parent 71b1e41 commit 8964cf5

File tree

2 files changed

+574
-0
lines changed

2 files changed

+574
-0
lines changed

tests/test_strings.py

Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
#!/usr/bin/python3
2+
# -*- coding: utf-8 -*-
3+
4+
"""
5+
Unit tests for the strings() functionality.
6+
"""
7+
8+
import unittest
9+
from winappdbg.search import AsciiStringsPattern, UnicodeStringsPattern
10+
11+
12+
class TestAsciiStringsPattern(unittest.TestCase):
13+
"""Test the AsciiStringsPattern class."""
14+
15+
def test_basic_extraction(self):
16+
"""Test basic ASCII string extraction."""
17+
pattern = AsciiStringsPattern(minLength=4)
18+
data = b"Hello World! This is a test."
19+
20+
# Initialize the pattern with data
21+
pattern.data = data
22+
pattern.pos = 0
23+
24+
# Find first match
25+
pos = pattern.next_match()
26+
self.assertGreaterEqual(pos, 0)
27+
self.assertEqual(
28+
data[pos : pos + len(pattern)], b"Hello World! This is a test."
29+
)
30+
31+
def test_minimum_length(self):
32+
"""Test minimum length filtering."""
33+
pattern = AsciiStringsPattern(minLength=10)
34+
data = b"Hi\x00\x00Long enough string here\x00Short"
35+
36+
pattern.data = data
37+
pattern.pos = 0
38+
39+
# Should find the long string
40+
pos = pattern.next_match()
41+
self.assertGreaterEqual(pos, 0)
42+
match = data[pos : pos + len(pattern)]
43+
self.assertGreaterEqual(len(match), 10)
44+
45+
def test_binary_data_filtering(self):
46+
"""Test that binary data is filtered out."""
47+
pattern = AsciiStringsPattern(minLength=4)
48+
data = b"\x00\x01\x02\x03Hello\x00\x01\x02World"
49+
50+
pattern.data = data
51+
pattern.pos = 0
52+
53+
# Find first string
54+
pos = pattern.next_match()
55+
self.assertGreaterEqual(pos, 0)
56+
match = data[pos : pos + len(pattern)]
57+
self.assertEqual(match, b"Hello")
58+
59+
# Find next string
60+
pattern.pos = pos + len(pattern)
61+
pos = pattern.next_match()
62+
self.assertGreaterEqual(pos, 0)
63+
match = data[pos : pos + len(pattern)]
64+
self.assertEqual(match, b"World")
65+
66+
def test_no_match(self):
67+
"""Test when no strings are found."""
68+
pattern = AsciiStringsPattern(minLength=4)
69+
data = b"\x00\x01\x02\x03\x04\x05"
70+
71+
pattern.data = data
72+
pattern.pos = 0
73+
74+
# Should not find any strings
75+
pos = pattern.next_match()
76+
self.assertEqual(pos, -1)
77+
78+
def test_multiple_strings(self):
79+
"""Test extracting multiple strings from data."""
80+
pattern = AsciiStringsPattern(minLength=4)
81+
data = b"First\x00\x00Second\x00Third"
82+
83+
pattern.data = data
84+
pattern.pos = 0
85+
86+
strings = []
87+
while True:
88+
pos = pattern.next_match()
89+
if pos < 0:
90+
break
91+
match = data[pos : pos + len(pattern)]
92+
strings.append(match)
93+
pattern.pos = pos + len(pattern)
94+
95+
self.assertEqual(len(strings), 3)
96+
self.assertEqual(strings[0], b"First")
97+
self.assertEqual(strings[1], b"Second")
98+
self.assertEqual(strings[2], b"Third")
99+
100+
101+
class TestUnicodeStringsPattern(unittest.TestCase):
102+
"""Test the UnicodeStringsPattern class."""
103+
104+
def test_basic_extraction(self):
105+
"""Test basic Unicode string extraction."""
106+
pattern = UnicodeStringsPattern(minLength=4)
107+
# "Hello" in UTF-16LE
108+
data = b"H\x00e\x00l\x00l\x00o\x00"
109+
110+
pattern.data = data
111+
pattern.pos = 0
112+
113+
# Find match
114+
pos = pattern.next_match()
115+
self.assertGreaterEqual(pos, 0)
116+
match = data[pos : pos + len(pattern)]
117+
self.assertEqual(match, b"H\x00e\x00l\x00l\x00o\x00")
118+
119+
def test_minimum_length(self):
120+
"""Test minimum length filtering."""
121+
pattern = UnicodeStringsPattern(minLength=10)
122+
# "Hello" is too short (5 chars), "Long enough" is 11 chars
123+
data = (
124+
b"H\x00i\x00\x00\x00L\x00o\x00n\x00g\x00 \x00e\x00n\x00o\x00u\x00g\x00h\x00"
125+
)
126+
127+
pattern.data = data
128+
pattern.pos = 0
129+
130+
# Should skip "Hi" and find "Long enough"
131+
pos = pattern.next_match()
132+
self.assertGreaterEqual(pos, 0)
133+
match = data[pos : pos + len(pattern)]
134+
# Match should be at least 20 bytes (10 chars * 2 bytes)
135+
self.assertGreaterEqual(len(match), 20)
136+
137+
def test_mixed_data(self):
138+
"""Test Unicode extraction from mixed binary data."""
139+
pattern = UnicodeStringsPattern(minLength=4)
140+
# Binary data followed by "Test" in UTF-16LE
141+
data = b"\x00\x01\x02\x03T\x00e\x00s\x00t\x00\x00\x01\x02"
142+
143+
pattern.data = data
144+
pattern.pos = 0
145+
146+
# Find the Unicode string
147+
pos = pattern.next_match()
148+
self.assertGreaterEqual(pos, 0)
149+
match = data[pos : pos + len(pattern)]
150+
self.assertEqual(match, b"T\x00e\x00s\x00t\x00")
151+
152+
def test_no_match(self):
153+
"""Test when no Unicode strings are found."""
154+
pattern = UnicodeStringsPattern(minLength=4)
155+
# ASCII data without proper UTF-16LE encoding
156+
data = b"Hello World"
157+
158+
pattern.data = data
159+
pattern.pos = 0
160+
161+
# Should not find Unicode strings in ASCII data
162+
pos = pattern.next_match()
163+
self.assertEqual(pos, -1)
164+
165+
def test_multiple_unicode_strings(self):
166+
"""Test extracting multiple Unicode strings."""
167+
pattern = UnicodeStringsPattern(minLength=4)
168+
# "First" and "Second" in UTF-16LE with binary data between
169+
data = (
170+
b"F\x00i\x00r\x00s\x00t\x00\x00\x00\x01\x02S\x00e\x00c\x00o\x00n\x00d\x00"
171+
)
172+
173+
pattern.data = data
174+
pattern.pos = 0
175+
176+
strings = []
177+
while True:
178+
pos = pattern.next_match()
179+
if pos < 0:
180+
break
181+
match = data[pos : pos + len(pattern)]
182+
strings.append(match)
183+
pattern.pos = pos + len(pattern)
184+
185+
self.assertEqual(len(strings), 2)
186+
self.assertEqual(strings[0], b"F\x00i\x00r\x00s\x00t\x00")
187+
self.assertEqual(strings[1], b"S\x00e\x00c\x00o\x00n\x00d\x00")
188+
189+
190+
class TestPatternIntegration(unittest.TestCase):
191+
"""Test integration of pattern classes."""
192+
193+
def test_both_patterns_on_mixed_data(self):
194+
"""Test using both ASCII and Unicode patterns on mixed data."""
195+
# Mix of ASCII and UTF-16LE strings
196+
data = (
197+
b"ASCII text here"
198+
b"\x00\x00\x01\x02"
199+
b"U\x00n\x00i\x00c\x00o\x00d\x00e\x00"
200+
b"\x00\x01\x02\x03"
201+
b"More ASCII"
202+
)
203+
204+
# Test ASCII pattern
205+
ascii_pattern = AsciiStringsPattern(minLength=4)
206+
ascii_pattern.data = data
207+
ascii_pattern.pos = 0
208+
209+
ascii_strings = []
210+
while True:
211+
pos = ascii_pattern.next_match()
212+
if pos < 0:
213+
break
214+
match = data[pos : pos + len(ascii_pattern)]
215+
ascii_strings.append(match)
216+
ascii_pattern.pos = pos + len(ascii_pattern)
217+
218+
self.assertGreater(len(ascii_strings), 0)
219+
self.assertIn(b"ASCII text here", ascii_strings)
220+
self.assertIn(b"More ASCII", ascii_strings)
221+
222+
# Test Unicode pattern
223+
unicode_pattern = UnicodeStringsPattern(minLength=4)
224+
unicode_pattern.data = data
225+
unicode_pattern.pos = 0
226+
227+
unicode_strings = []
228+
while True:
229+
pos = unicode_pattern.next_match()
230+
if pos < 0:
231+
break
232+
match = data[pos : pos + len(unicode_pattern)]
233+
unicode_strings.append(match)
234+
unicode_pattern.pos = pos + len(unicode_pattern)
235+
236+
self.assertGreater(len(unicode_strings), 0)
237+
self.assertIn(b"U\x00n\x00i\x00c\x00o\x00d\x00e\x00", unicode_strings)
238+
239+
240+
if __name__ == "__main__":
241+
unittest.main()

0 commit comments

Comments
 (0)