Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
8761 | rgimad | 1 | ; EntropyView - file entropy visualisation |
2 | ; rgimad 2021 |
||
3 | |||
4 | ; header: |
||
5 | use32 |
||
6 | org 0 |
||
7 | db 'MENUET01' ; magic |
||
8 | dd 1 ; header version |
||
9 | dd _start ; entry point |
||
10 | dd _i_end ; program size |
||
11 | dd _mem ; memory size |
||
12 | dd _stacktop ; stack top addr |
||
13 | dd cmdline ; buf for args |
||
14 | dd 0 ; reversed |
||
15 | |||
16 | |||
17 | __DEBUG__ = 1 ; 0 - disable debug output / 1 - enable debug output |
||
18 | __DEBUG_LEVEL__ = DBG_ERR ; set the debug level |
||
19 | |||
20 | DBG_ALL = 0 ; all messages |
||
21 | DBG_INFO = 1 ; info and errors |
||
22 | DBG_ERR = 2 ; only errors |
||
23 | |||
24 | WND_START_X = 200 |
||
25 | WND_START_Y = 200 |
||
26 | WND_WIDTH = 540 |
||
27 | WND_HEIGHT = 275 |
||
28 | |||
29 | COL_KOEF = 7 |
||
30 | COL_WIDTH = 2 |
||
31 | HIST_Y = 230 |
||
32 | HIST_X = 10 |
||
33 | |||
34 | TMP_BUF_SIZE = 4096 |
||
35 | |||
36 | include '../../macros.inc' |
||
37 | purge mov, add, sub |
||
38 | |||
39 | include '../../debug-fdo.inc' |
||
40 | include '../../proc32.inc' |
||
41 | |||
42 | _start: |
||
43 | cmp byte [cmdline], 0 ; if no argument then print usage and exit |
||
44 | jne @f |
||
45 | |||
46 | mov dword [notify_struct.msg], msg_print_usage |
||
47 | mcall 70, notify_struct |
||
48 | mcall -1 |
||
49 | @@: |
||
50 | stdcall calculate_entropy |
||
51 | |||
52 | ; print the byte table (for debug purposes) |
||
53 | ; xor ecx, ecx |
||
54 | ; .table_loop: |
||
55 | ; cmp ecx, 256 |
||
56 | ; jae .end_table_loop |
||
57 | ; mov ebx, dword [byte_table + ecx*4] |
||
58 | |||
59 | ; DEBUGF DBG_INFO, "number of bytes %x = %u\n", ecx, ebx |
||
60 | |||
61 | ; inc ecx |
||
62 | ; jmp .table_loop |
||
63 | ; .end_table_loop: |
||
64 | |||
65 | |||
66 | ; event loop: |
||
67 | event_loop: |
||
68 | mcall 10 ; wait for event |
||
69 | |||
70 | cmp eax, 1 ; redraw event |
||
71 | je on_redraw |
||
72 | |||
73 | cmp eax,3 ; button event |
||
74 | je on_button |
||
75 | |||
76 | jmp event_loop |
||
77 | |||
78 | |||
79 | on_button: |
||
80 | mcall 17 ; 17 - get key code |
||
81 | cmp ah, 1 ; if key with code 1 is not pressed then continue |
||
82 | jne event_loop |
||
83 | mcall -1 ; else exit |
||
84 | |||
85 | ; define and draw window |
||
86 | align 4 |
||
87 | on_redraw: |
||
88 | mcall 12, 1 ; begin redraw |
||
89 | mcall 48, 3, sc,sizeof.system_colors |
||
90 | |||
91 | mov edx, [sc.work] ; background color |
||
92 | or edx, 0x34000000 ; window type |
||
93 | mcall 0, |
||
94 | |||
95 | ; draw bottom line |
||
96 | mov eax, 38 |
||
97 | mov ebx, HIST_X |
||
98 | shl ebx, 16 |
||
99 | add ebx, HIST_X + COL_WIDTH*255 |
||
100 | mov ecx, HIST_Y |
||
101 | shl ecx, 16 |
||
102 | add ecx, HIST_Y |
||
103 | mov edx, 0x00FF0000 |
||
104 | int 0x40 |
||
105 | |||
106 | ; visualize table: |
||
107 | xor ecx, ecx |
||
108 | .table_loop: |
||
109 | cmp ecx, 256 |
||
110 | jae .end_table_loop |
||
111 | mov ebx, dword [byte_table + ecx*4] ; ebx = frequency of ecx value |
||
112 | |||
113 | mov esi, ecx |
||
114 | imul esi, COL_WIDTH ; esi = x of column |
||
115 | |||
116 | push COL_KOEF |
||
117 | fild dword [esp] |
||
118 | add esp, 4 |
||
119 | |||
120 | push ebx |
||
121 | fild dword [esp] |
||
122 | add esp, 4 |
||
123 | |||
124 | fyl2x ; fpu stack top = COL_KOEF*log_2(ebx) |
||
125 | |||
126 | sub esp, 4 |
||
127 | fistp dword [esp] |
||
128 | pop eax |
||
129 | |||
130 | mov ebp, eax ; ebp = height of column |
||
131 | mov edi, HIST_Y |
||
132 | sub edi, eax ; edi = y of left upper corner of column |
||
133 | |||
134 | push ecx |
||
135 | ; DEBUGF DBG_INFO, "drawing rect x = %u y = %u, height = %u\n", esi, edi, ebp |
||
136 | mov eax, 13 |
||
137 | mov ebx, esi |
||
138 | add ebx, HIST_X |
||
139 | shl ebx, 16 |
||
140 | add ebx, COL_WIDTH - 1 |
||
141 | mov ecx, edi |
||
142 | shl ecx, 16 |
||
143 | add ecx, ebp |
||
144 | mov edx, 0x80000000 |
||
145 | int 0x40 |
||
146 | pop ecx |
||
147 | |||
148 | |||
149 | inc ecx |
||
150 | jmp .table_loop |
||
151 | .end_table_loop: |
||
152 | ; DEBUGF DBG_INFO, "esi = %u\n", esi |
||
153 | |||
154 | mcall 12, 2 ; end draw |
||
155 | jmp event_loop |
||
156 | |||
157 | ; calculate entropy of file |
||
158 | align 4 |
||
159 | proc calculate_entropy stdcall |
||
160 | stdcall _memset, byte_table, 0, 256*4 |
||
161 | mov dword [file_size], 0 |
||
162 | DEBUGF DBG_INFO, "starting reading blocks...\n" |
||
163 | .read_block: |
||
164 | mov eax, 70 |
||
165 | mov ebx, fread_struct |
||
166 | int 0x40 |
||
167 | |||
168 | add dword [fread_struct.offset_low], ebx ; add how many was read |
||
169 | ; mov ebp, dword [fread_struct.offset_low] |
||
170 | ; DEBUGF DBG_INFO, "file pos = %u\n", ebp |
||
171 | |||
172 | cmp eax, 6 ; if EOF its normal so skip next check |
||
173 | je @f |
||
174 | |||
175 | test eax, eax ; if error occured |
||
176 | jnz .fail |
||
177 | |||
178 | @@: |
||
179 | mov edx, TMP_BUF_SIZE |
||
180 | cmp eax, 6 |
||
181 | jne @f |
||
182 | mov edx, ebx ; if eof then use how many read, not max block size |
||
183 | @@: |
||
184 | xor ecx, ecx |
||
185 | .buf_loop: |
||
186 | cmp ecx, edx |
||
187 | jae .end_buf_loop |
||
188 | |||
189 | movzx ebx, byte [tmp_buf + ecx] |
||
190 | shl ebx, 2 ; ebx *= 4; |
||
191 | add ebx, byte_table |
||
192 | inc dword [ebx] |
||
193 | inc ecx |
||
194 | jmp .buf_loop |
||
195 | .end_buf_loop: |
||
196 | |||
197 | cmp eax, 6 ; if EOF |
||
198 | je .end_read |
||
199 | |||
200 | jmp .read_block |
||
201 | |||
202 | .end_read: |
||
203 | mov eax, dword [fread_struct.offset_low] |
||
204 | mov dword [file_size], eax |
||
205 | DEBUGF DBG_INFO, "calculate_entropy end...\n" |
||
206 | ret |
||
207 | |||
208 | .fail: |
||
209 | DEBUGF DBG_ERR, "error reading file, code = %u\n", eax |
||
210 | mov dword [notify_struct.msg], msg_file_not_found |
||
211 | mcall 70, notify_struct |
||
212 | mcall -1 |
||
213 | ret |
||
214 | endp |
||
215 | |||
216 | |||
217 | align 4 |
||
218 | proc _memset stdcall, dest:dword, val:byte, cnt:dword ; doesnt clobber any registers |
||
219 | ;DEBUGF DBG_INFO, "memset(%x, %u, %u)\n", [dest], [val], [cnt] |
||
220 | push eax ecx edi |
||
221 | mov edi, dword [dest] |
||
222 | mov al, byte [val] |
||
223 | mov ecx, dword [cnt] |
||
224 | rep stosb |
||
225 | pop edi ecx eax |
||
226 | ret |
||
227 | endp |
||
228 | |||
229 | |||
230 | ; data: |
||
231 | include_debug_strings ; for debug-fdo |
||
232 | |||
233 | align 4 |
||
234 | fread_struct: |
||
235 | .subfunction dd 0 ; + 0 |
||
236 | .offset_low dd 0 ; + 4 |
||
237 | .offset_high dd 0 ; + 8 |
||
238 | .size dd TMP_BUF_SIZE ; + 12 |
||
239 | .buffer dd tmp_buf ; + 16 |
||
240 | db 0 ; + 20 |
||
241 | .filename: dd cmdline ; + 24 |
||
242 | |||
243 | file_size dd 0 |
||
244 | |||
245 | sc system_colors |
||
246 | wnd_title db 'EntropyView 0.0.1', 0 |
||
247 | msg_file_not_found db '"File not found" -tE', 0 |
||
248 | msg_print_usage db '"Use from shell like:\nentropyview somefile.txt" -tI', 0 |
||
249 | |||
250 | notify_struct: |
||
251 | dd 7 ; run application |
||
252 | dd 0 |
||
253 | .msg dd ? |
||
254 | dd 0 |
||
255 | dd 0 |
||
256 | db '/sys/@notify', 0 |
||
257 | |||
258 | ; reverved data: |
||
259 | |||
260 | align 16 |
||
261 | _i_end: |
||
262 | cmdline rb 1024 ; reserve for command line arguments |
||
263 | tmp_buf rb TMP_BUF_SIZE ; temporary buffer for reading file |
||
264 | byte_table rd 256 ; table which stores how many times each byte value(0-255) occured in the file |
||
265 | |||
266 | rb 4096 ; for stack |
||
267 | |||
268 | align 16 |
||
269 | _stacktop: ; stack top label, stack grows downwards |
||
270 | |||
271 | _mem: ; end |