1 /**
2 * @namespace biew_plugins_I
3 * @file plugins/disasm.c
4 * @brief This file contains universal interface for any disassembler.
5 * @version -
6 * @remark this source file is part of Binary vIEW project (BIEW).
7 * The Binary vIEW (BIEW) is copyright (C) 1995 Nickols_K.
8 * All rights reserved. This software is redistributable under the
9 * licence given in the file "Licence.en" ("Licence.ru" in russian
10 * translation) distributed in the BIEW archive.
11 * @note Requires POSIX compatible development system
12 *
13 * @author Nickols_K
14 * @since 1995
15 * @note Development, fixes and improvements
16 * @author Kostya Nosov <k-nosov@yandex.ru>
17 * @date 12.09.2000
18 * @note Adding virtual address as argument of jump and call insns
19 * @author Mauro Giachero
20 * @date 02.11.2007
21 * @note Reworked inline assemblers support
22 **/
23 #include <string.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <limits.h>
27 #include <errno.h>
28 #include <ctype.h>
29
30 #include "colorset.h"
31 #include "bmfile.h"
32 #include "bin_util.h"
33 #include "plugins/hexmode.h"
34 #include "plugins/disasm.h"
35 #include "biewutil.h"
36 #include "reg_form.h"
37 #include "bconsole.h"
38 #include "editor.h"
39 #include "codeguid.h"
40 #include "search.h"
41 #include "tstrings.h"
42 #include "biewlib/file_ini.h"
43 #include "biewlib/biewlib.h"
44 #include "biewlib/pmalloc.h"
45 #include "biewlib/kbd_code.h"
46
47 extern REGISTRY_DISASM ix86_Disasm;
48 extern REGISTRY_DISASM Null_Disasm;
49 extern REGISTRY_DISASM AVR_Disasm;
50 extern REGISTRY_DISASM ARM_Disasm;
51 extern REGISTRY_DISASM PPC_Disasm;
52 extern REGISTRY_DISASM Java_Disasm;
53
54 static REGISTRY_DISASM *mainDisasmTable[] =
55 {
56 &Null_Disasm,
57 &ix86_Disasm,
58 &Java_Disasm,
59 &AVR_Disasm,
60 &ARM_Disasm,
61 &PPC_Disasm
62 };
63
64 static unsigned DefDisasmSel = __DEFAULT_DISASM;
65 REGISTRY_DISASM *activeDisasm = NULL;
66
67 static unsigned long PrevPageSize,CurrPageSize,PrevStrLen,CurrStrLen;
68 unsigned disNeedRef = 0;
69 int DisasmCurrLine;
70 unsigned disPanelMode = 0;
71 static int HiLight = 1;
72 static unsigned char *CurrStrLenBuff = NULL;
73 static unsigned long *PrevStrLenAddr = NULL;
74 static char LastPrevLen;
75 static char PrevStrCount = 0;
76 static char * disCodeBuffer = NULL,*disCodeBuf2 = NULL;
77 static char * disCodeBufPredict = NULL;
78 static int disMaxCodeLen;
79
80 tBool DisasmPrepareMode = False;
81
82 char * dis_comments;
83 unsigned dis_severity;
84
85 static void __NEAR__ __FASTCALL__ disAcceptActions( void );
86
disSelect_Disasm(void)87 static tBool __FASTCALL__ disSelect_Disasm( void )
88 {
89 const char *modeName[sizeof(mainDisasmTable)/sizeof(REGISTRY_DISASM *)];
90 size_t i,nModes;
91 int retval;
92
93 nModes = sizeof(mainDisasmTable)/sizeof(REGISTRY_DISASM *);
94 for(i = 0;i < nModes;i++) modeName[i] = mainDisasmTable[i]->name;
95 retval = SelBoxA(modeName,nModes," Select disassembler: ",DefDisasmSel);
96 if(retval != -1)
97 {
98 if(activeDisasm->term) activeDisasm->term();
99 activeDisasm = mainDisasmTable[retval];
100 DefDisasmSel = retval;
101 disAcceptActions();
102 return True;
103 }
104 return False;
105 }
106
FillPrevAsmPage(__filesize_t bound,unsigned predist)107 static void __FASTCALL__ FillPrevAsmPage(__filesize_t bound,unsigned predist)
108 {
109 __filesize_t distin,addr;
110 unsigned j;
111 unsigned totallen;
112 tAbsCoord height = twGetClientHeight(MainWnd);
113 char showref,addrdet;
114 if(!predist) predist = height*disMaxCodeLen;
115 predist = (predist/16)*16+16; /** align on 16-byte boundary */
116 distin = bound >= predist ? bound - predist : 0;
117 memset(PrevStrLenAddr,TWC_DEF_FILLER,height*sizeof(long));
118 PrevStrCount = 0;
119 totallen = 0;
120 showref = disNeedRef;
121 addrdet = hexAddressResolv;
122 hexAddressResolv = 0;
123 disNeedRef = 0;
124 DisasmPrepareMode = True;
125 for(j = 0;;j++)
126 {
127 DisasmRet dret;
128 addr = distin + totallen;
129 BMReadBufferEx(disCodeBuffer,disMaxCodeLen,addr,BM_SEEK_SET);
130 dret = Disassembler(distin,(void *)disCodeBuffer,__DISF_SIZEONLY);
131 if(addr >= bound) break;
132 totallen += dret.codelen;
133 if(j < height) PrevStrLenAddr[j] = addr;
134 else
135 {
136 memmove(PrevStrLenAddr,&PrevStrLenAddr[1],(height - 1)*sizeof(long));
137 PrevStrLenAddr[height - 1] = addr;
138 }
139 }
140 PrevStrCount = j < height ? j : height;
141 LastPrevLen = PrevStrCount ? bound - PrevStrLenAddr[PrevStrCount - 1] : 0;
142 disNeedRef = showref;
143 DisasmPrepareMode = False;
144 hexAddressResolv = addrdet;
145 }
146
PrepareAsmLines(int keycode,__filesize_t cfpos)147 static void __FASTCALL__ PrepareAsmLines(int keycode,__filesize_t cfpos)
148 {
149 tAbsCoord height = twGetClientHeight(MainWnd);
150 switch(keycode)
151 {
152 case KE_DOWNARROW:
153 PrevStrLen = CurrStrLenBuff[0];
154 CurrStrLen = CurrStrLenBuff[1];
155 if((unsigned)PrevStrCount < height) PrevStrCount++;
156 else memmove(PrevStrLenAddr,&PrevStrLenAddr[1],sizeof(long)*(height - 1));
157 PrevStrLenAddr[PrevStrCount - 1] = cfpos - CurrStrLenBuff[0];
158 PrevPageSize = PrevStrLenAddr[PrevStrCount - 1] - PrevStrLenAddr[0] + PrevStrLen;
159 break;
160 case KE_PGDN:
161 {
162 size_t i;
163 unsigned size;
164 __filesize_t prevpos;
165 size = Summ(CurrStrLenBuff,height);
166 prevpos = cfpos - size;
167 size = 0;
168 for(i = 0;i < height;i++)
169 {
170 size += CurrStrLenBuff[i];
171 PrevStrLenAddr[i] = prevpos + size;
172 }
173 PrevStrLen = CurrStrLenBuff[height - 1];
174 PrevPageSize = size;
175 PrevStrCount = height;
176 }
177 break;
178 case KE_UPARROW:
179 FillPrevAsmPage(cfpos,(unsigned)(PrevPageSize + 15));
180 goto Calc;
181 default:
182 FillPrevAsmPage(cfpos,0);
183 Calc:
184 if(PrevStrCount)
185 {
186 PrevStrLen = LastPrevLen;
187 PrevPageSize = PrevStrLenAddr[PrevStrCount - 1] + LastPrevLen - PrevStrLenAddr[0];
188 }
189 else
190 {
191 PrevStrLen = 0;
192 PrevPageSize = 0;
193 }
194 break;
195 }
196 }
197
drawAsm(unsigned keycode,unsigned textshift)198 static unsigned __FASTCALL__ drawAsm( unsigned keycode, unsigned textshift )
199 {
200 int i,I,Limit,dir,orig_commpos,orig_commoff;
201 size_t j,len,len_64;
202 __filesize_t cfpos,flen,TopCFPos;
203 static __filesize_t amocpos = 0L;
204 char outstr[__TVIO_MAXSCREENWIDTH];
205 char savstring[20];
206 HLInfo hli;
207 ColorAttr cattr;
208 flen = BMGetFLength();
209 cfpos = TopCFPos = BMGetCurrFilePos();
210 if(keycode == KE_UPARROW)
211 {
212 char showref,addrdet;
213 DisasmRet dret;
214 showref = disNeedRef;
215 addrdet = hexAddressResolv;
216 disNeedRef = hexAddressResolv = 0;
217 BMReadBufferEx(disCodeBuffer,disMaxCodeLen,cfpos,BM_SEEK_SET);
218 DisasmPrepareMode = True;
219 dret = Disassembler(cfpos,(void *)disCodeBuffer,__DISF_SIZEONLY);
220 if(cfpos + dret.codelen != amocpos && cfpos && amocpos) keycode = KE_SUPERKEY;
221 DisasmPrepareMode = False;
222 disNeedRef = showref;
223 hexAddressResolv = addrdet;
224 }
225 PrepareAsmLines(keycode,cfpos);
226 if(amocpos != cfpos || keycode == KE_SUPERKEY || keycode == KE_JUSTFIND)
227 {
228 tAbsCoord height = twGetClientHeight(MainWnd);
229 tAbsCoord width = twGetClientWidth(MainWnd);
230 GidResetGoAddress(keycode);
231 I = 0;
232 twFreezeWin(MainWnd);
233 if(keycode == KE_UPARROW)
234 {
235 dir = -1;
236 Limit = -1;
237 /* All checks we have done above */
238 twScrollWinDn(MainWnd,1,1);
239 memmove(&CurrStrLenBuff[1],CurrStrLenBuff,height-1);
240 }
241 else
242 {
243 dir = 1;
244 Limit = height;
245 }
246 if(keycode == KE_DOWNARROW)
247 {
248 if(CurrStrLenBuff[1])
249 {
250 I = height-1;
251 twScrollWinUp(MainWnd,I,1);
252 memmove(CurrStrLenBuff,&CurrStrLenBuff[1],I);
253 cfpos += Summ(CurrStrLenBuff,I);
254 }
255 else
256 {
257 twRefreshWin(MainWnd);
258 goto bye;
259 }
260 }
261 if(cfpos > flen) cfpos = flen;
262 amocpos = cfpos;
263 twUseWin(MainWnd);
264 for(i = I;i != Limit;i+=1*dir)
265 {
266 DisasmRet dret;
267 memset(outstr,TWC_DEF_FILLER,__TVIO_MAXSCREENWIDTH);
268 DisasmCurrLine = i;
269 if(cfpos < flen)
270 {
271 len = cfpos + disMaxCodeLen < flen ? disMaxCodeLen : (int)(flen - cfpos);
272 memset(disCodeBuffer,0,disMaxCodeLen);
273 BMReadBufferEx((void *)disCodeBuffer,len,cfpos,BM_SEEK_SET);
274 dret = Disassembler(cfpos,(void *)disCodeBuffer,__DISF_NORMAL);
275 if(i == 0) CurrStrLen = dret.codelen;
276 CurrStrLenBuff[i] = dret.codelen;
277 twSetColorAttr(browser_cset.main);
278 len_64=HA_LEN;
279 memcpy(outstr,GidEncodeAddress(cfpos,hexAddressResolv),len_64);
280 len = 0;
281 if(disPanelMode < PANMOD_FULL)
282 {
283 static char _clone;
284 len = len_64;
285 twDirectWrite(1,i + 1,outstr,len);
286 if(!hexAddressResolv)
287 {
288 twSetColorAttr(disasm_cset.family_id);
289 _clone = activeDisasm->CloneShortName(dret.pro_clone);
290 twDirectWrite(len_64,i + 1,&_clone,1);
291 twSetColorAttr(browser_cset.main);
292 }
293 }
294 if(disPanelMode < PANMOD_MEDIUM)
295 {
296 unsigned full_off,med_off,tmp_off;
297 ColorAttr opc;
298 med_off = disMaxCodeLen*2+1;
299 full_off = med_off+len_64;
300 for(j = 0;j < dret.codelen;j++,len+=2)
301 memcpy(&outstr[len],Get2Digit(disCodeBuffer[j]),2);
302 tmp_off = disPanelMode < PANMOD_FULL ? full_off : med_off;
303 if(len < tmp_off) len = tmp_off;
304 if(activeDisasm->GetOpcodeColor)
305 opc = HiLight == 2 ? activeDisasm->altGetOpcodeColor(dret.pro_clone) :
306 HiLight == 1 ? activeDisasm->GetOpcodeColor(dret.pro_clone) : disasm_cset.opcodes;
307 else opc = disasm_cset.opcodes;
308 twSetColorAttr(opc);
309 twDirectWrite(disPanelMode < PANMOD_FULL ? len_64+1 : 1,
310 i + 1,
311 &outstr[len_64],
312 disPanelMode < PANMOD_FULL ? len - (len_64+1) : len - 1);
313 if(isHOnLine(cfpos,dret.codelen))
314 {
315 hli.text = &outstr[len_64];
316 HiLightSearch(MainWnd,cfpos,len_64,dret.codelen,i,&hli,HLS_USE_DOUBLE_WIDTH);
317 }
318 }
319 twSetColorAttr(browser_cset.main);
320 twDirectWrite(len,i + 1," ",1); len++;
321 cattr = HiLight == 2 ? activeDisasm->altGetInsnColor(dret.pro_clone) :
322 HiLight == 1 ? activeDisasm->GetInsnColor(dret.pro_clone) :
323 browser_cset.main;
324 twSetColorAttr(cattr);
325 j = strlen(dret.str);
326 /* Here adding commentaries */
327 savstring[0] = 0;
328 orig_commoff = orig_commpos = 0;
329 if(j > 5)
330 if(dret.str[j-5] == codeguid_image[0] &&
331 dret.str[j-4] == codeguid_image[1] &&
332 dret.str[j-3] == codeguid_image[2] &&
333 dret.str[j-1] == codeguid_image[4] &&
334 dis_severity > DISCOMSEV_NONE)
335 {
336 int new_idx;
337 orig_commpos = new_idx = j-5;
338 orig_commoff = len;
339 strcpy(savstring,&dret.str[new_idx]);
340 dret.str[new_idx--] = 0;
341 while(dret.str[new_idx] == ' ' && new_idx) new_idx--;
342 if(dret.str[new_idx] != ' ') new_idx++;
343 dret.str[new_idx] = 0;
344 j = strlen(dret.str);
345 }
346 twDirectWrite(len,i+1,dret.str,j); len += j;
347 if(dis_severity > DISCOMSEV_NONE)
348 {
349 twSetColorAttr(disasm_cset.comments);
350 twGotoXY(len,i+1);
351 twPutS(" ; "); len+=3;
352 j = orig_commpos-len;
353 j = min(j,strlen(dis_comments));
354 twDirectWrite(len,i+1,dis_comments,j);
355 len += j;
356 if(savstring[0])
357 {
358 twGotoXY(len,i+1);
359 twClrEOL();
360 twSetColorAttr(cattr);
361 len = orig_commoff + orig_commpos;
362 twDirectWrite(len,i+1,savstring,5);
363 len += 5;
364 }
365 }
366 twSetColorAttr(browser_cset.main);
367 if(len < width)
368 {
369 twGotoXY(len,i + 1);
370 twClrEOL();
371 }
372 cfpos += dret.codelen;
373 BMSeek(cfpos,BM_SEEK_SET);
374 }
375 else
376 {
377 twDirectWrite(1,i + 1,outstr,width);
378 CurrStrLenBuff[i] = 0;
379 }
380 }
381 twRefreshWin(MainWnd);
382 twSetColorAttr(browser_cset.main);
383 lastbyte = TopCFPos + Summ(CurrStrLenBuff,height);
384 CurrPageSize = lastbyte-TopCFPos;
385 }
386 bye:
387 return textshift;
388 }
389
disPrevPageSize(void)390 static unsigned long __FASTCALL__ disPrevPageSize( void ) { return PrevPageSize; }
disCurrPageSize(void)391 static unsigned long __FASTCALL__ disCurrPageSize( void ) { return CurrPageSize; }
disPrevLineWidth(void)392 static unsigned long __FASTCALL__ disPrevLineWidth( void ) { return PrevStrLen; }
disCurrLineWidth(void)393 static unsigned long __FASTCALL__ disCurrLineWidth( void ) { return CurrStrLen; }
disMiscKeyName(void)394 static const char * __FASTCALL__ disMiscKeyName( void ) { return "Modify"; }
395
396 static const char *refsdepth_names[] =
397 {
398 "~None",
399 "~Calls/jmps only (navigation)",
400 "~All",
401 "Reference ~prediction (mostly full)"
402 };
403
disReferenceResolving(void)404 static tBool __FASTCALL__ disReferenceResolving( void )
405 {
406 size_t nModes;
407 int retval;
408 tBool ret;
409 nModes = sizeof(refsdepth_names)/sizeof(char *);
410 retval = SelBoxA(refsdepth_names,nModes," Reference resolving depth: ",disNeedRef);
411 if(retval != -1)
412 {
413 disNeedRef = retval;
414 ret = True;
415 }
416 else ret = False;
417 if(detectedFormat->set_state)
418 detectedFormat->set_state(disNeedRef ? PS_ACTIVE : PS_INACTIVE);
419 return ret;
420 }
421
422 static const char *panmod_names[] =
423 {
424 "~Full",
425 "~Medium",
426 "~Wide"
427 };
428
disSelectPanelMode(void)429 static tBool __FASTCALL__ disSelectPanelMode( void )
430 {
431 unsigned nModes;
432 int i;
433 nModes = sizeof(panmod_names)/sizeof(char *);
434 i = SelBoxA(panmod_names,nModes," Select panel mode: ",disPanelMode);
435 if(i != -1)
436 {
437 disPanelMode = i;
438 return True;
439 }
440 return False;
441 }
442
443 static const char *hilight_names[] =
444 {
445 "~Mono",
446 "~Highlight",
447 "~Alt Highlight"
448 };
449
disSelectHiLight(void)450 static tBool __FASTCALL__ disSelectHiLight( void )
451 {
452 unsigned nModes;
453 int i;
454 nModes = sizeof(hilight_names)/sizeof(char *);
455 i = SelBoxA(hilight_names,nModes," Select highlight mode: ",HiLight);
456 if(i != -1)
457 {
458 HiLight = i;
459 return True;
460 }
461 return False;
462 }
463
disDetect(void)464 static tBool __FASTCALL__ disDetect( void ) { return True; }
465
DefAsmAction(int _lastbyte,int start)466 static tBool __FASTCALL__ DefAsmAction(int _lastbyte,int start)
467 {
468 int _index;
469 tBool redraw,dox;
470 char xx;
471 redraw = True;
472 xx = edit_x / 2;
473 dox = True;
474 _index = start + xx;
475 switch(_lastbyte)
476 {
477 case KE_F(4) : EditorMem.buff[_index] = ~EditorMem.buff[_index]; break;
478 case KE_F(5) : EditorMem.buff[_index] |= edit_XX; break;
479 case KE_F(6) : EditorMem.buff[_index] &= edit_XX; break;
480 case KE_F(7) : EditorMem.buff[_index] ^= edit_XX; break;
481 case KE_F(8) : EditorMem.buff[_index] = edit_XX; break;
482 case KE_F(9) : EditorMem.buff[_index] = EditorMem.save[_index]; break;
483 default : redraw = edit_defaction(_lastbyte); dox = False; break;
484 }
485 if(dox) { xx++; edit_x = xx*2; }
486 return redraw;
487 }
488
DisasmScreen(TWindow * ewnd,__filesize_t cp,__filesize_t flen,int st,int stop,int start)489 static void __FASTCALL__ DisasmScreen(TWindow* ewnd,__filesize_t cp,__filesize_t flen,int st,int stop,int start)
490 {
491 int i,j,len,lim,len_64;
492 char outstr[__TVIO_MAXSCREENWIDTH+1],outstr1[__TVIO_MAXSCREENWIDTH+1];
493 tAbsCoord width = twGetClientWidth(MainWnd);
494 DisasmRet dret;
495 twFreezeWin(ewnd);
496 for(i = st;i < stop;i++)
497 {
498 if(start + cp < flen)
499 {
500 len_64=HA_LEN;
501 memcpy(outstr,GidEncodeAddress(cp + start,hexAddressResolv),len_64);
502 twUseWin(MainWnd);
503 twSetColorAttr(browser_cset.main);
504 twDirectWrite(1,i + 1,outstr,len_64-1);
505 dret = Disassembler(cp + start,&EditorMem.buff[start],__DISF_NORMAL);
506 EditorMem.alen[i] = dret.codelen;
507 memset(outstr,TWC_DEF_FILLER,width);
508 memset(outstr1,TWC_DEF_FILLER,width);
509 len = 0; for(j = 0;j < EditorMem.alen[i];j++) { memcpy(&outstr1[len],Get2Digit(EditorMem.save[start + j]),2); len += 2; }
510 len = 0; for(j = 0;j < EditorMem.alen[i];j++) { memcpy(&outstr[len],Get2Digit(EditorMem.buff[start + j]),2); len += 2; }
511 twUseWin(ewnd);
512 len = disMaxCodeLen*2;
513 for(j = 0;j < len;j++)
514 {
515 twSetColorAttr(outstr[j] == outstr1[j] ? browser_cset.edit.main : browser_cset.edit.change);
516 twDirectWrite(j + 1,i + 1,&outstr[j],1);
517 }
518 len = strlen(dret.str);
519 memset(outstr,TWC_DEF_FILLER,width);
520 memcpy(outstr,dret.str,len);
521 twUseWin(MainWnd);
522 twSetColorAttr(browser_cset.main);
523 lim = disMaxCodeLen*2+len_64+1;
524 twDirectWrite(lim+1,i + 1,outstr,width-lim);
525 start += EditorMem.alen[i];
526 }
527 else
528 {
529 twUseWin(MainWnd);
530 twGotoXY(1,i + 1);
531 twClrEOL();
532 twUseWin(ewnd);
533 twGotoXY(1,i + 1);
534 twClrEOL();
535 EditorMem.alen[i] = 0;
536 }
537 }
538 twRefreshWin(ewnd);
539 }
540
FullAsmEdit(TWindow * ewnd)541 static int __NEAR__ __FASTCALL__ FullAsmEdit(TWindow * ewnd)
542 {
543 int j,_lastbyte,start;
544 unsigned rlen,len,flags;
545 __filesize_t flen;
546 unsigned max_buff_size = disMaxCodeLen*tvioHeight;
547 tAbsCoord height = twGetClientHeight(MainWnd);
548 tBool redraw = False;
549 char outstr[__TVIO_MAXSCREENWIDTH],owork[__TVIO_MAXSCREENWIDTH];
550
551 flen = BMGetFLength();
552 edit_cp = BMGetCurrFilePos();
553 start = 0;
554
555 rlen = (__filesize_t)edit_cp + max_buff_size < flen ? max_buff_size : (unsigned)(flen - edit_cp);
556 BMReadBufferEx((void *)EditorMem.buff,rlen,edit_cp,BM_SEEK_SET);
557 memcpy(EditorMem.save,EditorMem.buff,max_buff_size);
558 memset(EditorMem.alen,TWC_DEF_FILLER,height);
559
560 DisasmScreen(ewnd,edit_cp,flen,0,height,start);
561 PaintETitle(0,True);
562 start = 0;
563 twShowWin(ewnd);
564 twSetCursorType(TW_CUR_NORM);
565 while(1)
566 {
567 twUseWin(ewnd);
568
569 len = 0; for(j = 0;j < EditorMem.alen[edit_y];j++) { memcpy(&owork[len],Get2Digit(EditorMem.save[start + j]),2); len += 2; }
570 len = 0; for(j = 0;j < EditorMem.alen[edit_y];j++) { memcpy(&outstr[len],Get2Digit(EditorMem.buff[start + j]),2); len += 2; }
571 flags = __ESS_FILLER_7BIT | __ESS_WANTRETURN | __ESS_HARDEDIT;
572 if(!redraw) flags |= __ESS_NOREDRAW;
573 _lastbyte = eeditstring(outstr,&legalchars[2],&len,(unsigned)(edit_y + 1),(unsigned *)&edit_x,
574 flags,owork,NULL);
575 CompressHex(&EditorMem.buff[start],outstr,EditorMem.alen[edit_y],False);
576 switch(_lastbyte)
577 {
578 case KE_CTL_F(4):
579 {
580 AsmRet aret;
581 if(activeDisasm->asm_f)
582 {
583 char code[81];
584 code[0]='\0';
585 if(GetStringDlg(code,activeDisasm->name,
586 NULL,"Enter assembler instruction:"))
587 {
588 aret = (*activeDisasm->asm_f)(code);
589 if(aret.err_code)
590 {
591 char *message="Syntax error";
592 if (aret.insn[0])
593 {
594 message=aret.insn;
595 }
596 ErrMessageBox(message,NULL);
597 continue;
598 }
599 else
600 {
601 int i;
602 char bytebuffer[3];
603
604 for (i=aret.insn_len-1; i>=0; i--)
605 {
606 sprintf(bytebuffer, "%0.2x", aret.insn[i]);
607 ungotstring(bytebuffer);
608 }
609 }
610 }
611 break;
612 }
613 else
614 {
615 ErrMessageBox("Sorry, no assembler available",NULL);
616 continue;
617 }
618 }
619 case KE_F(1) : ExtHelp(); continue;
620 case KE_CTL_F(1): activeDisasm->action[0](); continue;
621 case KE_CTL_F(2): SelectSysInfo(); continue;
622 case KE_CTL_F(3): SelectTool(); continue;
623 case KE_F(2) :
624 {
625 BGLOBAL bHandle;
626 char *fname;
627 fname = BMName();
628 if((bHandle = biewOpenRW(fname,BBIO_SMALL_CACHE_SIZE)) != &bNull)
629 {
630 bioSeek(bHandle,edit_cp,BIO_SEEK_SET);
631 if(!bioWriteBuffer(bHandle,(void *)EditorMem.buff,rlen))
632 errnoMessageBox(WRITE_FAIL,NULL,errno);
633 bioClose(bHandle);
634 BMReRead();
635 }
636 else errnoMessageBox("Can't reopen",NULL,errno);
637 }
638 case KE_F(10):
639 case KE_ESCAPE: goto bye;
640 default: redraw = DefAsmAction(_lastbyte,start); break;
641 }
642 CheckYBounds();
643 start = edit_y ? Summ(EditorMem.alen,edit_y) : 0;
644 if(redraw)
645 {
646 DisasmRet dret;
647 dret = Disassembler(edit_cp + start,&EditorMem.buff[start],__DISF_NORMAL);
648 EditorMem.alen[edit_y] = dret.codelen;
649 DisasmScreen(ewnd,edit_cp,flen,0,height,0);
650 }
651 PaintETitle(start + edit_x/2,True);
652 CheckXYBounds();
653 start = edit_y ? Summ(EditorMem.alen,edit_y) : 0;
654 }
655 bye:
656 twSetCursorType(TW_CUR_OFF);
657 return _lastbyte;
658 }
659
disEdit(void)660 static void __FASTCALL__ disEdit( void )
661 {
662 unsigned len_64;
663 TWindow * ewnd;
664 len_64=HA_LEN;
665 if(!BMGetFLength()) { ErrMessageBox(NOTHING_EDIT,NULL); return; }
666 ewnd = WindowOpen(len_64+1,2,disMaxCodeLen*2+len_64+1,tvioHeight-1,TWS_CURSORABLE);
667 twSetColorAttr(browser_cset.edit.main); twClearWin();
668 edit_x = edit_y = 0;
669 EditMode = EditMode ? False : True;
670 if(editInitBuffs(disMaxCodeLen,NULL,0))
671 {
672 FullAsmEdit(ewnd);
673 editDestroyBuffs();
674 }
675 EditMode = EditMode ? False : True;
676 CloseWnd(ewnd);
677 PaintTitle();
678 }
679
HelpAsm(void)680 static void __FASTCALL__ HelpAsm( void )
681 {
682 if( activeDisasm->ShowShortHelp ) activeDisasm->ShowShortHelp();
683 }
684
disReadIni(hIniProfile * ini)685 static void __FASTCALL__ disReadIni( hIniProfile *ini )
686 {
687 char tmps[10];
688 if(isValidIniArgs())
689 {
690 biewReadProfileString(ini,"Biew","Browser","LastSubMode","0",tmps,sizeof(tmps));
691 DefDisasmSel = (int)strtoul(tmps,NULL,10);
692 if(DefDisasmSel >= sizeof(mainDisasmTable)/sizeof(REGISTRY_DISASM *)) DefDisasmSel = 0;
693 ReadIniAResolv(ini);
694 biewReadProfileString(ini,"Biew","Browser","SubSubMode7","0",tmps,sizeof(tmps));
695 disPanelMode = (int)strtoul(tmps,NULL,10);
696 if(disPanelMode > PANMOD_FULL) disPanelMode = 0;
697 biewReadProfileString(ini,"Biew","Browser","SubSubMode8","0",tmps,sizeof(tmps));
698 disNeedRef = (int)strtoul(tmps,NULL,10);
699 if(disNeedRef > NEEDREF_PREDICT) disNeedRef = 0;
700 biewReadProfileString(ini,"Biew","Browser","SubSubMode9","0",tmps,sizeof(tmps));
701 HiLight = (int)strtoul(tmps,NULL,10);
702 if(HiLight > 2) HiLight = 2;
703 activeDisasm = mainDisasmTable[DefDisasmSel];
704 disAcceptActions();
705 if(activeDisasm->read_ini) activeDisasm->read_ini(ini);
706 }
707 }
708
disInit(void)709 static void __FASTCALL__ disInit( void )
710 {
711 unsigned i;
712 unsigned def_platform;
713 CurrStrLenBuff = PMalloc(tvioHeight);
714 PrevStrLenAddr = PMalloc(tvioHeight*sizeof(long));
715 dis_comments = PMalloc(DISCOM_SIZE*sizeof(char));
716 if((!CurrStrLenBuff) || (!PrevStrLenAddr) || (!dis_comments))
717 {
718 err:
719 MemOutBox("Disassembler initialization");
720 exit(EXIT_FAILURE);
721 }
722 def_platform = DISASM_DATA;
723 if(detectedFormat->query_platform) def_platform = detectedFormat->query_platform();
724 activeDisasm = mainDisasmTable[0];
725 DefDisasmSel = DISASM_DATA;
726 for(i=0;i<sizeof(mainDisasmTable)/sizeof(REGISTRY_DISASM *);i++) {
727 if(mainDisasmTable[i]->type == def_platform) {
728 activeDisasm=mainDisasmTable[i];
729 DefDisasmSel = def_platform;
730 break;
731 }
732 }
733 disAcceptActions();
734 if(!initCodeGuider()) goto err;
735 }
736
disTerm(void)737 static void __FASTCALL__ disTerm( void )
738 {
739 termCodeGuider();
740 if(activeDisasm->term) activeDisasm->term();
741 PFREE(CurrStrLenBuff);
742 PFREE(PrevStrLenAddr);
743 PFREE(dis_comments);
744 PFREE(disCodeBuffer);
745 PFREE(disCodeBuf2);
746 PFREE(disCodeBufPredict);
747 }
748
disSaveIni(hIniProfile * ini)749 static void __FASTCALL__ disSaveIni( hIniProfile *ini )
750 {
751 char tmps[10];
752 sprintf(tmps,"%i",DefDisasmSel);
753 biewWriteProfileString(ini,"Biew","Browser","LastSubMode",tmps);
754 WriteIniAResolv(ini);
755 sprintf(tmps,"%i",disPanelMode);
756 biewWriteProfileString(ini,"Biew","Browser","SubSubMode7",tmps);
757 sprintf(tmps,"%i",disNeedRef);
758 biewWriteProfileString(ini,"Biew","Browser","SubSubMode8",tmps);
759 sprintf(tmps,"%i",HiLight);
760 biewWriteProfileString(ini,"Biew","Browser","SubSubMode9",tmps);
761 if(activeDisasm->save_ini) activeDisasm->save_ini(ini);
762 }
763
Disassembler(__filesize_t ulShift,MBuffer buffer,unsigned flags)764 DisasmRet Disassembler(__filesize_t ulShift,MBuffer buffer,unsigned flags)
765 {
766 dis_comments[0] = 0;
767 dis_severity = DISCOMSEV_NONE;
768 return activeDisasm->disasm(ulShift,buffer,flags);
769 }
770
disCharSize(void)771 static unsigned __FASTCALL__ disCharSize( void ) { return 1; }
772
disSearch(TWindow * pwnd,__filesize_t start,__filesize_t * slen,unsigned flags,tBool is_continue,tBool * is_found)773 static __filesize_t __FASTCALL__ disSearch(TWindow *pwnd, __filesize_t start,
774 __filesize_t *slen, unsigned flags,
775 tBool is_continue, tBool *is_found)
776 {
777 DisasmRet dret;
778 __filesize_t tsize, retval, flen, dfpos, cfpos, sfpos; /* If search have no result */
779 char *disSearchBuff;
780 unsigned len, lw, proc, pproc, pmult;
781 int cache[UCHAR_MAX+1];
782 cfpos = sfpos = BMGetCurrFilePos();
783 flen = BMGetFLength();
784 retval = FILESIZE_MAX;
785 disSearchBuff = PMalloc(1002+DISCOM_SIZE);
786 DumpMode = True;
787 if(!disSearchBuff)
788 {
789 MemOutBox("Disassembler search initialization");
790 goto bye;
791 }
792 cfpos = start;
793 tsize = flen;
794 pmult = 100;
795 if(tsize > FILESIZE_MAX/100) { tsize /= 100; pmult = 1; }
796 pproc = proc = 0;
797 /* Attempt to balance disassembler output */
798 PrepareAsmLines(KE_SUPERKEY, cfpos);
799 lw = disPrevLineWidth();
800 if(cfpos && cfpos >= lw) cfpos -= lw;
801 if(!(is_continue && (flags & SF_REVERSE))) cfpos += disCurrLineWidth();
802 /* end of attempt */
803 fillBoyerMooreCache(cache, search_buff, search_len, flags & SF_CASESENS);
804 while(1)
805 {
806 proc = (unsigned)((cfpos*pmult)/tsize);
807 if(proc != pproc)
808 {
809 if(!ShowPercentInWnd(pwnd,pproc=proc)) break;
810 }
811 if(flags & SF_REVERSE)
812 {
813 PrepareAsmLines(KE_UPARROW, cfpos);
814 lw = disPrevLineWidth();
815 if(cfpos && lw && cfpos >= lw)
816 {
817 len = cfpos + disMaxCodeLen < flen ? disMaxCodeLen : (int)(flen - cfpos);
818 memset(disCodeBuffer,0,disMaxCodeLen);
819 dfpos = cfpos;
820 BMReadBufferEx((void *)disCodeBuffer,len,cfpos,BM_SEEK_SET);
821 dret = Disassembler(cfpos,(void *)disCodeBuffer,__DISF_NORMAL);
822 cfpos -= lw;
823 }
824 else break;
825 }
826 else
827 {
828 len = cfpos + disMaxCodeLen < flen ? disMaxCodeLen : (int)(flen - cfpos);
829 memset(disCodeBuffer,0,disMaxCodeLen);
830 dfpos = cfpos;
831 BMReadBufferEx((void *)disCodeBuffer,len,cfpos,BM_SEEK_SET);
832 dret = Disassembler(cfpos,(void *)disCodeBuffer,__DISF_NORMAL);
833 cfpos += dret.codelen;
834 if(cfpos >= flen) break;
835 }
836 strcpy(disSearchBuff, dret.str);
837 strcat(disSearchBuff, dis_comments);
838 if(strFind(disSearchBuff, strlen(disSearchBuff), search_buff, search_len, cache, flags))
839 {
840 *is_found = True;
841 retval = dfpos;
842 *slen = dret.codelen;
843 break;
844 }
845 }
846 PFREE(disSearchBuff);
847 bye:
848 BMSeek(sfpos, SEEK_SET);
849 DumpMode = False;
850 return retval;
851 }
852
853 REGISTRY_MODE disMode =
854 {
855 "~Disassembler",
856 { NULL, "Disasm", NULL, NULL, NULL, "AResol", "PanMod", "ResRef", "HiLght", "UsrNam" },
857 { NULL, disSelect_Disasm, NULL, NULL, NULL, hexAddressResolution, disSelectPanelMode, disReferenceResolving, disSelectHiLight, udnUserNames },
858 disDetect,
859 __MF_USECODEGUIDE | __MF_DISASM,
860 drawAsm,
861 NULL,
862 disCharSize,
863 disMiscKeyName,
864 disEdit,
865 disPrevPageSize,
866 disCurrPageSize,
867 disPrevLineWidth,
868 disCurrLineWidth,
869 HelpAsm,
870 disReadIni,
871 disSaveIni,
872 disInit,
873 disTerm,
874 disSearch
875 };
876
disAcceptActions(void)877 static void __NEAR__ __FASTCALL__ disAcceptActions( void )
878 {
879 if(activeDisasm->init) activeDisasm->init();
880 disMaxCodeLen = activeDisasm->max_insn_len();
881 if(disCodeBuffer) PFREE(disCodeBuffer);
882 disCodeBuffer = PMalloc(disMaxCodeLen);
883 if(disCodeBuf2) PFREE(disCodeBuf2);
884 disCodeBuf2 = PMalloc(disMaxCodeLen);
885 if(disCodeBufPredict) PFREE(disCodeBufPredict);
886 disCodeBufPredict = PMalloc(disMaxCodeLen*PREDICT_DEPTH);
887 if(!(disCodeBuffer && disCodeBuf2 && disCodeBufPredict))
888 {
889 MemOutBox("Disassembler initialization");
890 exit(EXIT_FAILURE);
891 }
892 disMode.prompt[0] = activeDisasm->prompt[0];
893 disMode.action[0] = activeDisasm->action[0];
894 disMode.prompt[2] = activeDisasm->prompt[1];
895 disMode.action[2] = activeDisasm->action[1];
896 disMode.prompt[3] = activeDisasm->prompt[2];
897 disMode.action[3] = activeDisasm->action[2];
898 disMode.prompt[4] = activeDisasm->prompt[3];
899 disMode.action[4] = activeDisasm->action[3];
900 }
901
902 /** Common disassembler utility */
903
TabSpace(char * str,unsigned nSpace)904 char * __FASTCALL__ TabSpace(char * str,unsigned nSpace)
905 {
906 int i,mx;
907 unsigned len;
908 len = strlen(str);
909 mx = max(len,nSpace);
910 for(i = len;i < mx;i++) str[i] = TWC_DEF_FILLER;
911 if(len >= nSpace) str[i++] = TWC_DEF_FILLER;
912 str[i] = 0;
913 return str;
914 }
915
disSetModifier(char * str,const char * modf)916 void __FASTCALL__ disSetModifier(char *str,const char *modf)
917 {
918 unsigned i,len,mlen;
919 i = 0;
920 len = strlen(str);
921 mlen = strlen(modf);
922 while(str[i] != TWC_DEF_FILLER) i++;
923 i++;
924 memcpy(&str[i],modf,mlen);
925 if(i+mlen > len) { str[i+mlen] = TWC_DEF_FILLER; str[i+mlen+1] = 0; }
926 }
927
disAppendDigits(char * str,__filesize_t ulShift,int flags,char codelen,void * defval,unsigned type)928 int __FASTCALL__ disAppendDigits(char *str,__filesize_t ulShift,int flags,
929 char codelen,void *defval,unsigned type)
930 {
931 unsigned long app;
932 char comments[DISCOM_SIZE];
933 const char *appstr;
934 unsigned dig_type;
935 __filesize_t fpos;
936 fpos = bmGetCurrFilePos();
937 #ifndef NDEBUG
938 if(ulShift >= BMGetFLength()-codelen)
939 {
940 char sout[75];
941 static tBool displayed = False;
942 if(!displayed)
943 {
944 strncpy(sout,str,sizeof(sout)-1);
945 sout[sizeof(sout)-1] = 0;
946 if(!strlen(sout)) strcpy(sout,"disAppendDigits");
947 ErrMessageBox(sout," Internal disassembler error detected ");
948 displayed = True;
949 COREDUMP();
950 }
951 }
952 #endif
953 if(hexAddressResolv && detectedFormat->AddressResolving) flags |= APREF_SAVE_VIRT;
954 app = disNeedRef >= NEEDREF_ALL ? AppendAsmRef(str,ulShift,flags,codelen,0L) :
955 RAPREF_NONE;
956 if(app != RAPREF_DONE)
957 {
958 dig_type = type & 0x00FFU;
959 comments[0] = 0;
960 /* @todo Remove dependencies from 4-byte size of operand */
961 /* Only if immediate operand */
962 if(((type & DISARG_IMM) || (type & DISARG_DISP) ||
963 (type & DISARG_IDXDISP) || (type & DISARG_RIP)) &&
964 disNeedRef >= NEEDREF_PREDICT) /* Only when reference prediction is on */
965 {
966 tUInt64 _defval;
967 unsigned fld_len=1;
968 switch(dig_type)
969 {
970 default:
971 case DISARG_BYTE: _defval = *(tUInt8 *)defval; fld_len=1; break;
972 case DISARG_CHAR: _defval = *(tInt8 *)defval; fld_len=1; break;
973 case DISARG_WORD: _defval = *(tUInt16 *)defval; fld_len=2; break;
974 case DISARG_SHORT:_defval = *(tInt16 *)defval; fld_len=2; break;
975 case DISARG_DWORD:_defval = *(tUInt32 *)defval; fld_len=4; break;
976 case DISARG_LONG: _defval = *(tInt32 *)defval; fld_len=4; break;
977 case DISARG_QWORD:_defval = *(tUInt64 *)defval; fld_len=8; break;
978 case DISARG_LLONG:_defval = *(tInt64 *)defval; fld_len=8; break;
979 }
980 if(_defval) /* Do not perform operation on NULL */
981 {
982 __filesize_t pa,psym;
983 unsigned _class;
984 if(type & DISARG_RIP) {
985 _defval += (detectedFormat->pa2va ?
986 detectedFormat->pa2va(ulShift) :
987 ulShift)+fld_len;
988 }
989 if(!app) pa = detectedFormat->va2pa ? detectedFormat->va2pa(_defval) :
990 _defval;
991 else pa = app;
992 if(pa)
993 {
994 /* 1. Try to determine immediate as offset to public symbol */
995 if(type & DISARG_RIP) app = AppendAsmRef(str,pa,flags,codelen,0L);
996 if(app == RAPREF_DONE) goto next_step;
997 if(dis_severity < DISCOMSEV_FUNC)
998 {
999 strcpy(comments,".*");
1000 if(detectedFormat->GetPubSym)
1001 {
1002 psym = detectedFormat->GetPubSym(&comments[2],sizeof(comments)-2,
1003 &_class,pa,False);
1004 if(psym != pa) comments[0] = 0;
1005 else
1006 {
1007 dis_severity = DISCOMSEV_FUNC;
1008 strcpy(dis_comments,comments);
1009 }
1010 }
1011 }
1012 /* 2. Try to determine immediate as offset to string constant */
1013 comments[0] = 0;
1014 if(dis_severity < DISCOMSEV_STRPTR)
1015 {
1016 size_t index;
1017 unsigned char rch;
1018 index = 0;
1019 strcat(comments,"->\"");
1020 for(index = 3;index < sizeof(comments)-5;index++)
1021 {
1022 bmSeek(pa+index-3,BM_SEEK_SET);
1023 rch = bmReadByte();
1024 if(isprint(rch)) comments[index] = rch;
1025 else break;
1026 }
1027 if(!comments[3]) comments[0] = 0;
1028 else
1029 {
1030 comments[index++] = '"'; comments[index] = 0;
1031 dis_severity = DISCOMSEV_STRPTR;
1032 strcpy(dis_comments,comments);
1033 }
1034 }
1035 }
1036 }
1037 }
1038 next_step:
1039 comments[0] = 0;
1040 if(app == RAPREF_NONE)
1041 {
1042 switch(dig_type)
1043 {
1044 case DISARG_LLONG:
1045 #ifdef INT64_C
1046 appstr = Get16SignDig(*(tInt64 *)defval);
1047 #else
1048 appstr = Get16SignDig(((tInt32 *)defval)[0],((tInt32 *)defval)[1]);
1049 #endif
1050 if(type & DISARG_IMM &&
1051 disNeedRef >= NEEDREF_PREDICT &&
1052 dis_severity < DISCOMSEV_STRING &&
1053 isprint(((unsigned char *)defval)[0]) &&
1054 isprint(((unsigned char *)defval)[1]) &&
1055 isprint(((unsigned char *)defval)[2]) &&
1056 isprint(((unsigned char *)defval)[3]) &&
1057 isprint(((unsigned char *)defval)[4]) &&
1058 isprint(((unsigned char *)defval)[5]) &&
1059 isprint(((unsigned char *)defval)[6]) &&
1060 isprint(((unsigned char *)defval)[7]))
1061 sprintf(comments,"\"%c%c%c%c%c%c%c%c\""
1062 ,((unsigned char *)defval)[0]
1063 ,((unsigned char *)defval)[1]
1064 ,((unsigned char *)defval)[2]
1065 ,((unsigned char *)defval)[3]
1066 ,((unsigned char *)defval)[4]
1067 ,((unsigned char *)defval)[5]
1068 ,((unsigned char *)defval)[6]
1069 ,((unsigned char *)defval)[7]);
1070 break;
1071 case DISARG_LONG: appstr = Get8SignDig(*(tInt32 *)defval);
1072 if(type & DISARG_IMM &&
1073 disNeedRef >= NEEDREF_PREDICT &&
1074 dis_severity < DISCOMSEV_STRING &&
1075 isprint(((unsigned char *)defval)[0]) &&
1076 isprint(((unsigned char *)defval)[1]) &&
1077 isprint(((unsigned char *)defval)[2]) &&
1078 isprint(((unsigned char *)defval)[3]))
1079 sprintf(comments,"\"%c%c%c%c\""
1080 ,((unsigned char *)defval)[0]
1081 ,((unsigned char *)defval)[1]
1082 ,((unsigned char *)defval)[2]
1083 ,((unsigned char *)defval)[3]);
1084 break;
1085 case DISARG_SHORT: appstr = Get4SignDig(*(tInt16 *)defval);
1086 if(type & DISARG_IMM &&
1087 disNeedRef >= NEEDREF_PREDICT &&
1088 dis_severity < DISCOMSEV_STRING &&
1089 isprint(((unsigned char *)defval)[0]) &&
1090 isprint(((unsigned char *)defval)[1]))
1091 sprintf(comments,"\"%c%c\""
1092 ,((unsigned char *)defval)[0]
1093 ,((unsigned char *)defval)[1]);
1094 break;
1095 case DISARG_CHAR: appstr = Get2SignDig(*(char *)defval);
1096 if(type & DISARG_IMM &&
1097 disNeedRef >= NEEDREF_PREDICT &&
1098 dis_severity < DISCOMSEV_STRING &&
1099 isprint(*(unsigned char *)defval))
1100 sprintf(comments,"'%c'",*(unsigned char *)defval);
1101 break;
1102 case DISARG_BYTE: appstr = Get2Digit(*(unsigned char *)defval);
1103 if(type & DISARG_IMM &&
1104 disNeedRef >= NEEDREF_PREDICT &&
1105 dis_severity < DISCOMSEV_STRING &&
1106 isprint(*(unsigned char *)defval))
1107 sprintf(comments,"'%c'",*(unsigned char *)defval);
1108 break;
1109 case DISARG_WORD: appstr = Get4Digit(*(tUInt16 *)defval);
1110 if(type & DISARG_IMM &&
1111 disNeedRef >= NEEDREF_PREDICT &&
1112 dis_severity < DISCOMSEV_STRING &&
1113 isprint(((unsigned char *)defval)[0]) &&
1114 isprint(((unsigned char *)defval)[1]))
1115 sprintf(comments,"\"%c%c\""
1116 ,((unsigned char *)defval)[0]
1117 ,((unsigned char *)defval)[1]);
1118 break;
1119 default:
1120 case DISARG_DWORD: appstr = Get8Digit(*(tUInt32 *)defval);
1121 if(type & DISARG_IMM &&
1122 disNeedRef >= NEEDREF_PREDICT &&
1123 dis_severity < DISCOMSEV_STRING &&
1124 isprint(((unsigned char *)defval)[0]) &&
1125 isprint(((unsigned char *)defval)[1]) &&
1126 isprint(((unsigned char *)defval)[2]) &&
1127 isprint(((unsigned char *)defval)[3]))
1128 sprintf(comments,"\"%c%c%c%c\""
1129 ,((unsigned char *)defval)[0]
1130 ,((unsigned char *)defval)[1]
1131 ,((unsigned char *)defval)[2]
1132 ,((unsigned char *)defval)[3]);
1133 break;
1134 case DISARG_QWORD:
1135 #ifdef INT64_C
1136 appstr = Get16Digit(*(tUInt64 *)defval);
1137 #else
1138 appstr = Get16Digit(((tUInt32 *)defval)[0],((tUInt32 *)defval)[1]);
1139 #endif
1140 if(type & DISARG_IMM &&
1141 disNeedRef >= NEEDREF_PREDICT &&
1142 dis_severity < DISCOMSEV_STRING &&
1143 isprint(((unsigned char *)defval)[0]) &&
1144 isprint(((unsigned char *)defval)[1]) &&
1145 isprint(((unsigned char *)defval)[2]) &&
1146 isprint(((unsigned char *)defval)[3]) &&
1147 isprint(((unsigned char *)defval)[4]) &&
1148 isprint(((unsigned char *)defval)[5]) &&
1149 isprint(((unsigned char *)defval)[6]) &&
1150 isprint(((unsigned char *)defval)[7]))
1151 sprintf(comments,"\"%c%c%c%c%c%c%c%c\""
1152 ,((unsigned char *)defval)[0]
1153 ,((unsigned char *)defval)[1]
1154 ,((unsigned char *)defval)[2]
1155 ,((unsigned char *)defval)[3]
1156 ,((unsigned char *)defval)[4]
1157 ,((unsigned char *)defval)[5]
1158 ,((unsigned char *)defval)[6]
1159 ,((unsigned char *)defval)[7]);
1160 break;
1161 }
1162 strcat(str,appstr);
1163 }
1164 if(comments[0])
1165 {
1166 dis_severity = DISCOMSEV_STRING;
1167 strcpy(dis_comments,comments);
1168 }
1169 }
1170 bmSeek(fpos,BM_SEEK_SET);
1171 return app;
1172 }
1173
disAppendFAddr(char * str,__fileoff_t ulShift,__fileoff_t distin,__filesize_t r_sh,char type,unsigned seg,char codelen)1174 int __FASTCALL__ disAppendFAddr(char * str,__fileoff_t ulShift,__fileoff_t distin,__filesize_t r_sh,char type,unsigned seg,char codelen)
1175 {
1176 int needref;
1177 __filesize_t fpos;
1178 char *modif_to;
1179 DisasmRet dret;
1180 int appended = RAPREF_NONE;
1181 int flags;
1182 fpos = bmGetCurrFilePos();
1183 memset(&dret,0,sizeof(DisasmRet));
1184 /* Prepare insn type */
1185 if(disNeedRef > NEEDREF_NONE)
1186 {
1187 /* Forward prediction: ulShift = offset of binded field but r_sh is
1188 pointer where this field is referenced. */
1189 memset(disCodeBufPredict,0,disMaxCodeLen*PREDICT_DEPTH);
1190 bmSeek(r_sh, SEEK_SET);
1191 bmReadBuffer(disCodeBufPredict,disMaxCodeLen*PREDICT_DEPTH);
1192 dret = Disassembler(r_sh,(MBuffer)disCodeBufPredict,__DISF_GETTYPE);
1193 }
1194 #ifndef NDEBUG
1195 if(ulShift >= (__fileoff_t)BMGetFLength()-codelen)
1196 {
1197 char sout[75];
1198 static tBool displayed = False;
1199 if(!displayed)
1200 {
1201 strncpy(sout,str,sizeof(sout)-1);
1202 sout[sizeof(sout)-1] = 0;
1203 if(!strlen(sout)) strcpy(sout,"disAppendFAddr");
1204 ErrMessageBox(sout," Internal disassembler error detected ");
1205 displayed = True;
1206 COREDUMP();
1207 }
1208 }
1209 #endif
1210 if(disNeedRef > NEEDREF_NONE)
1211 {
1212 if(dret.pro_clone == __INSNT_JMPPIC || dret.pro_clone == __INSNT_JMPRIP) goto try_pic; /* skip defaults for PIC */
1213 flags = APREF_TRY_LABEL;
1214 if(hexAddressResolv && detectedFormat->AddressResolving) flags |= APREF_SAVE_VIRT;
1215 if(AppendAsmRef(str,ulShift,flags,codelen,r_sh)) appended = RAPREF_DONE;
1216 else
1217 {
1218 /*
1219 Forwarding references.
1220 Dereferencing ret instruction.
1221 Idea and PE implementation by "Kostya Nosov" <k-nosov@yandex.ru>
1222 */
1223 if(dret.pro_clone == __INSNT_JMPVVT) /* jmp (mod r/m) */
1224 {
1225 if(AppendAsmRef(str,r_sh+dret.field,APREF_TRY_LABEL,dret.codelen,r_sh))
1226 {
1227 appended = RAPREF_DONE;
1228 modif_to = strchr(str,' ');
1229 if(modif_to)
1230 {
1231 while(*modif_to == ' ') modif_to++;
1232 *(modif_to-1) = '*';
1233 }
1234 if(!DumpMode && !EditMode) GidAddGoAddress(str,r_sh);
1235 }
1236 }
1237 else
1238 if(dret.pro_clone == __INSNT_JMPPIC) /* jmp [ebx+offset] */
1239 {
1240 try_pic:
1241 if(dret.pro_clone == __INSNT_JMPRIP) goto try_rip;
1242 if(AppendAsmRef(str,r_sh+dret.field,APREF_TRY_PIC,dret.codelen,r_sh))
1243 {
1244 appended = RAPREF_DONE; /* terminate appending any info anyway */
1245 if(!DumpMode && !EditMode) GidAddGoAddress(str,r_sh);
1246 }
1247 }
1248 else
1249 if(dret.pro_clone == __INSNT_JMPRIP) /* calln *(jmp [rip+offset]) */
1250 {
1251 __filesize_t _defval,fpos,pa;
1252 unsigned long app;
1253 try_rip:
1254 fpos = BMGetCurrFilePos();
1255 _defval = dret.codelen==8 ? BMReadQWordEx(r_sh+dret.field,SEEKF_START):
1256 BMReadDWordEx(r_sh+dret.field,SEEKF_START);
1257 BMSeek(fpos,SEEKF_START);
1258 _defval += (detectedFormat->pa2va ?
1259 detectedFormat->pa2va(r_sh+dret.field) :
1260 r_sh+dret.field)+dret.codelen;
1261 pa = detectedFormat->va2pa ? detectedFormat->va2pa(_defval) :
1262 _defval;
1263 app=AppendAsmRef(str,pa,APREF_TRY_LABEL,dret.codelen,0L);
1264 if(app)
1265 {
1266 appended = RAPREF_DONE; /* terminate appending any info anyway */
1267 modif_to = strchr(str,' ');
1268 if(modif_to)
1269 {
1270 while(*modif_to == ' ') modif_to++;
1271 *(modif_to-1) = '*';
1272 }
1273 if(!DumpMode && !EditMode) GidAddGoAddress(str,r_sh);
1274 }
1275 }
1276 }
1277 }
1278 /*
1279 Idea and PE release of "Kostya Nosov" <k-nosov@yandex.ru>:
1280 make virtual address as argument of "jxxx" and "callx"
1281 */
1282 if(!appended)
1283 {
1284 if(hexAddressResolv && detectedFormat->AddressResolving)
1285 {
1286 r_sh = r_sh ? r_sh : (__filesize_t)ulShift;
1287 appended = detectedFormat->AddressResolving(&str[strlen(str)],r_sh) ? RAPREF_DONE : RAPREF_NONE;
1288 }
1289 if(!appended)
1290 {
1291 needref = disNeedRef;
1292 disNeedRef = NEEDREF_NONE;
1293 if(r_sh <= BMGetFLength())
1294 {
1295 const char * cptr;
1296 char lbuf[20];
1297 cptr = DumpMode ? "L" : "file:";
1298 strcat(str,cptr);
1299 #if (__WORDSIZE >= 32) && !defined(__QNX4__)
1300 if((BMFileFlags&BMFF_USE64))
1301 sprintf(lbuf,"%016llX",r_sh);
1302 else
1303 #endif
1304 sprintf(lbuf,"%08lX",(unsigned long)r_sh);
1305 strcat(str,lbuf);
1306 appended = RAPREF_DONE;
1307 }
1308 else
1309 {
1310 const char * pstr = "";
1311 if(type & DISADR_USESEG)
1312 {
1313 strcat(str,Get4Digit(seg));
1314 strcat(str,":");
1315 }
1316 if(!type) pstr = Get2SignDig((char)distin);
1317 else
1318 if(type & DISADR_NEAR16)
1319 pstr = type & DISADR_USESEG ? Get4Digit((unsigned)distin) :
1320 Get4SignDig((unsigned)distin);
1321 else
1322 if(type & DISADR_NEAR32) pstr = Get8SignDig(distin);
1323 else
1324 if(type & DISADR_NEAR64) pstr = Get16SignDig(distin);
1325 strcat(str,pstr);
1326 }
1327 disNeedRef = needref;
1328 }
1329 if(disNeedRef >= NEEDREF_PREDICT && dis_severity < DISCOMSEV_INSNREF)
1330 {
1331 const char * comms;
1332 comms = NULL;
1333 switch(dret.pro_clone)
1334 {
1335 case __INSNT_RET: comms = "RETURN"; break;
1336 case __INSNT_LEAVE: comms = "LEAVE"; break;
1337 default: break;
1338 }
1339 if(comms)
1340 {
1341 dis_severity = DISCOMSEV_INSNREF;
1342 strcpy(dis_comments,comms);
1343 }
1344 }
1345 if(appended && !DumpMode && !EditMode) GidAddGoAddress(str,r_sh);
1346 }
1347 bmSeek(fpos,BM_SEEK_SET);
1348 return appended;
1349 }
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360