Snippets

Alexander Hanel Capstone wrapper using IDAPythons API names - In progress

Created by Alexander Hanel last modified
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
import struct 
import md5 
from capstone import *


class cs_db():
    """
    A class for storing the data to be disassembled 
    """
    def __init__(self, data, bit=32):
        self.data = data
        self.MAX_BYTE_SIZE = 15
        self.BADADDR = 0xffffffffffffffff
        if bit == 32:
            self.capstone = Cs(CS_ARCH_X86, CS_MODE_32)
        else:
            self.capstone = Cs(CS_ARCH_X86, CS_MODE_64)
            
   
#----------------------------------------------------------------------------
#                 C O M M O N   I N F O R M A T I O N
#----------------------------------------------------------------------------

# def GetIdaDirectory():
    # """
    # Get IDA directory
    # This function returns the directory where IDA.EXE resides
    # """
    # return ida_diskio.idadir("")


# def GetInputFile():
    # """
    # Get input file name
    # This function returns name of the file being disassembled
    # """
    # return ida_nalt.get_root_filename()


# def GetInputFilePath():
    # """
    # Get input file path
    # This function returns the full path of the file being disassembled
    # """
    # return ida_nalt.get_input_file_path()


# def SetInputFilePath(path):
    # """
    # Set input file name
    # This function updates the file name that is stored in the database
    # It is used by the debugger and other parts of IDA
    # Use it when the database is moved to another location or when you
    # use remote debugging.
    # @param path: new input file path
    # """
    # return ida_nalt.set_root_filename(path)


# def GetIdbPath():
    # """
    # Get IDB full path
    # This function returns full path of the current IDB database
    # """
    # return ida_idaapi.as_cstr(ida_loader.cvar.database_idb)


    def GetInputMD5(self):
        """
        Return the MD5 hash of the input binary file
        @return: MD5 string or None on error
        """
        return md5.new(self.data).hexdigest() 


# def GetFlags(ea):
    # """
    # Get internal flags
    # @param ea: linear address
    # @return: 32-bit value of internal flags. See start of IDC.IDC file
        # for explanations.
    # """
    # return ida_bytes.getFlags(ea)


# def IdbByte(ea):
    # """
    # Get one byte (8-bit) of the program at 'ea' from the database even if the debugger is active
    # @param ea: linear address
    # @return: byte value. If the byte has no value then 0xFF is returned.
    # @note: If the current byte size is different from 8 bits, then the returned value may have more 1's.
           # To check if a byte has a value, use this expr: hasValue(GetFlags(ea))
    # """
    # return ida_bytes.get_db_byte(ea)


    def GetManyBytes(self, ea, size):
        """
        Return the specified number of bytes of the program
        @param ea: linear address
        @param size: size of buffer in normal 8-bit bytes
        @param use_dbg: Removed
        @return: None on failure
                 otherwise a string containing the read bytes
        """
        temp = self.data[ea:ea+size]
        if len(temp) == size:
            return temp
        else:
            return None


    def Byte(self, ea):
        """
        Get value of program byte
        @param ea: linear address
        @return: value of byte. If byte has no value then returns 0xFF
            If the current byte size is different from 8 bits, then the returned value
            might have more 1's.
            To check if a byte has a value, use functions hasValue(GetFlags(ea))
        """
        try:
            return struct.unpack("<B", self.data[ea])[0]
        except:
            return None


# def __DbgValue(ea, len):
    # if len not in ida_idaapi.__struct_unpack_table:
        # return None
    # r = ida_idd.dbg_read_memory(ea, len)
    # return None if r is None else struct.unpack((">" if ida_ida.cvar.inf.mf else "<") + ida_idaapi.__struct_unpack_table[len][1], r)[0]


# def DbgByte(ea):
    # """
    # Get value of program byte using the debugger memory
    # @param ea: linear address
    # @return: The value or None on failure.
    # """
    # return __DbgValue(ea, 1)


# def DbgWord(ea):
    # """
    # Get value of program word using the debugger memory
    # @param ea: linear address
    # @return: The value or None on failure.
    # """
    # return __DbgValue(ea, 2)


# def DbgDword(ea):
    # """
    # Get value of program double-word using the debugger memory
    # @param ea: linear address
    # @return: The value or None on failure.
    # """
    # return __DbgValue(ea, 4)


# def DbgQword(ea):
    # """
    # Get value of program quadro-word using the debugger memory
    # @param ea: linear address
    # @return: The value or None on failure.
    # """
    # return __DbgValue(ea, 8)


# def DbgRead(ea, size):
    # """
    # Read from debugger memory.
    # @param ea: linear address
    # @param size: size of data to read
    # @return: data as a string. If failed, If failed, throws an exception
    # Thread-safe function (may be called only from the main thread and debthread)
    # """
    # return ida_idd.dbg_read_memory(ea, size)


# def DbgWrite(ea, data):
    # """
    # Write to debugger memory.
    # @param ea: linear address
    # @param data: string to write
    # @return: number of written bytes (-1 - network/debugger error)
    # Thread-safe function (may be called only from the main thread and debthread)
    # """
    # if not ida_idd.dbg_can_query():
        # return -1
    # elif len(data) > 0:
        # return ida_idd.dbg_write_memory(ea, data)


# def GetOriginalByte(ea):
    # """
    # Get original value of program byte
    # @param ea: linear address
    # @return: the original value of byte before any patch applied to it
    # """
    # return ida_bytes.get_original_byte(ea)


    def Word(self,ea):
        """
        Get value of program word (2 bytes)
        @param ea: linear address
        @return: the value of the word. If word has no value then returns 0xFFFF
            If the current byte size is different from 8 bits, then the returned value
            might have more 1's.
        """
        try:
            tmp = self.data[ea:ea+2]
            return struct.unpack("<H", tmp)[0]
        except:
            return None

    def Dword(self,ea):
        """
        Get value of program double word (4 bytes)
        @param ea: linear address
        @return: the value of the double word. If failed returns -1
        """
        try:
            tmp = self.data[ea:ea+4]
            return struct.unpack("<I", tmp)[0]
        except:
            return None


    def Qword(self,ea):
        """
        Get value of program quadro word (8 bytes)
        @param ea: linear address
        @return: the value of the quadro word. If failed, returns -1
        """
        try:
            tmp = self.data[ea:ea+8] 
            return struct.unpack("<Q", tmp)[0]
        except:
            return None


    def GetFloat(self,ea):
        """
        Get value of a floating point number (4 bytes)
        This function assumes number stored using IEEE format
        and in the same endianness as integers.
        @param ea: linear address
        @return: float
        """
        try:
            tmp = struct.pack("I", self.Dword(ea))
            return struct.unpack("f", tmp)[0]
        except:
            None

    def GetDouble(self, ea):
        """
        Get value of a floating point number (8 bytes)
        This function assumes number stored using IEEE format
        and in the same endianness as integers.
        @param ea: linear address
        @return: double
        """
        try:
            tmp = struct.pack("Q", self.Qword(ea))
            return struct.unpack("d", tmp)[0]
        except:
            return None 


# def LocByName(name):
    # """
    # Get linear address of a name
    # @param name: name of program byte
    # @return: address of the name
             # BADADDR - No such name
    # """
    # return ida_name.get_name_ea(BADADDR, name)


# def LocByNameEx(fromaddr, name):
    # """
    # Get linear address of a name
    # @param fromaddr: the referring address. Allows to retrieve local label
               # addresses in functions. If a local name is not found,
               # then address of a global name is returned.
    # @param name: name of program byte
    # @return: address of the name (BADADDR - no such name)
    # @note: Dummy names (like byte_xxxx where xxxx are hex digits) are parsed by this
           # function to obtain the address. The database is not consulted for them.
    # """
    # return ida_name.get_name_ea(fromaddr, name)


# def SegByBase(base):
    # """
    # Get segment by segment base
    # @param base: segment base paragraph or selector
    # @return: linear address of the start of the segment or BADADDR
             # if no such segment
    # """
    # sel = ida_segment.find_selector(base)
    # seg = ida_segment.get_segm_by_sel(sel)

    # if seg:
        # return seg.startEA
    # else:
        # return BADADDR


# def ScreenEA():
    # """
    # Get linear address of cursor
    # """
    # return ida_kernwin.get_screen_ea()


# def GetCurrentLine():
    # """
    # Get the disassembly line at the cursor
    # @return: string
    # """
    # return ida_lines.tag_remove(ida_kernwin.get_curline())


# def SelStart():
    # """
    # Get start address of the selected area
    # returns BADADDR - the user has not selected an area
    # """
    # selection, startaddr, endaddr = ida_kernwin.read_selection()

    # if selection == 1:
        # return startaddr
    # else:
        # return BADADDR


# def SelEnd():
    # """
    # Get end address of the selected area
    # @return: BADADDR - the user has not selected an area
    # """
    # selection, startaddr, endaddr = ida_kernwin.read_selection()

    # if selection == 1:
        # return endaddr
    # else:
        # return BADADDR


# def GetReg(ea, reg):
    # """
    # Get value of segment register at the specified address
    # @param ea: linear address
    # @param reg: name of segment register
    # @return: the value of the segment register or -1 on error
    # @note: The segment registers in 32bit program usually contain selectors,
           # so to get paragraph pointed to by the segment register you need to
           # call AskSelector() function.
    # """
    # reg = ida_idp.str2reg(reg);
    # if reg >= 0:
        # return ida_srarea.getSR(ea, reg)
    # else:
        # return -1

    def NextAddr(self,ea):
        """
        Get next address in the program
        @param ea: linear address
        @return: BADADDR - the specified address in the last used address
        """
        addr = ea + 1 
        if len(self.data) > addr > 0:
            return addr
        else:
            return self.BADADDR           

    def PrevAddr(self,ea):
        """
        Get previous address in the program
        @param ea: linear address
        @return: BADADDR - the specified address in the first address
        """
        addr = ea - 1 
        if len(self.data) > addr > 0:
            return addr
        else:
            return self.BADADDR


    def NextHead(self, ea):
        """
        Get next defined item (instruction or data) in the program
        @param ea: linear address to start search from
        @param maxea: the search will stop at the address
            maxea is not included in the search range
        @return: BADADDR - no (more) defined items
        """
        code = self.data[ea:ea + self.MAX_BYTE_SIZE]
        for (address, size, mnemonic, op_str) in self.capstone.disasm_lite(code, 0, 1):
            if size:
                return size + ea
            else:
                return self.BADADDR


    def PrevHead(self, ea, minea=0):
        """
        Get previous defined item (instruction or data) in the program
        @param ea: linear address to start search from
        @param minea: the search will stop at the address
                minea is included in the search range
        @return: BADADDR - no (more) defined items
        """
        # reverse loop, start at 15
        for offset in xrange(self.MAX_BYTE_SIZE, 0, -1):
            if ea - offset < 0:
                    continue
            code = self.data[ ea - offset: ea]
            for (address, size, mnemonic, op_str) in self.capstone.disasm_lite(code, 0, 1):
                if ea - offset + size == ea:
                    return ea - size
        return self.BADADDR


# def NextNotTail(ea):
    # """
    # Get next not-tail address in the program
    # This function searches for the next displayable address in the program.
    # The tail bytes of instructions and data are not displayable.
    # @param ea: linear address
    # @return: BADADDR - no (more) not-tail addresses
    # """
    # return ida_bytes.next_not_tail(ea)


# def PrevNotTail(ea):
    # """
    # Get previous not-tail address in the program
    # This function searches for the previous displayable address in the program.
    # The tail bytes of instructions and data are not displayable.
    # @param ea: linear address
    # @return: BADADDR - no (more) not-tail addresses
    # """
    # return ida_bytes.prev_not_tail(ea)


# def ItemHead(ea):
    # """
    # Get starting address of the item (instruction or data)
    # @param ea: linear address
    # @return: the starting address of the item
             # if the current address is unexplored, returns 'ea'
    # """
    # return ida_bytes.get_item_head(ea)


# def ItemEnd(ea):
    # """
    # Get address of the end of the item (instruction or data)
    # @param ea: linear address
    # @return: address past end of the item at 'ea'
    # """
    # return ida_bytes.get_item_end(ea)


# def ItemSize(ea):
    # """
    # Get size of instruction or data item in bytes
    # @param ea: linear address
    # @return: 1..n
    # """
    # return ida_bytes.get_item_end(ea) - ea


# def NameEx(fromaddr, ea):
    # """
    # Get visible name of program byte
    # This function returns name of byte as it is displayed on the screen.
    # If a name contains illegal characters, IDA replaces them by the
    # substitution character during displaying. See IDA.CFG for the
    # definition of the substitution character.
    # @param fromaddr: the referring address. May be BADADDR.
               # Allows to retrieve local label addresses in functions.
               # If a local name is not found, then a global name is
               # returned.
    # @param ea: linear address
    # @return: "" - byte has no name
    # """
    # name = ida_name.get_name(fromaddr, ea)

    # if not name:
        # return ""
    # else:
        # return name


# def GetTrueNameEx(fromaddr, ea):
    # """
    # Get true name of program byte
    # This function returns name of byte as is without any replacements.
    # @param fromaddr: the referring address. May be BADADDR.
           # Allows to retrieve local label addresses in functions.
           # If a local name is not found, then a global name is returned.
    # @param ea: linear address
    # @return: "" - byte has no name
    # """
    # name = ida_name.get_true_name(fromaddr, ea)

    # if not name:
        # return ""
    # else:
        # return name


# def Demangle(name, disable_mask):
    # """
    # Demangle a name
    # @param name: name to demangle
    # @param disable_mask: a mask that tells how to demangle the name
            # it is a good idea to get this mask using
            # GetLongPrm(INF_SHORT_DN) or GetLongPrm(INF_LONG_DN)
    # @return: a demangled name
        # If the input name cannot be demangled, returns None
    # """
    # return ida_name.demangle_name(name, disable_mask)


    def GetDisasmEx(self, ea, flags=0):
        """
        Get disassembly line
        @param ea: linear address of instruction
        @param flags: combination of the GENDSM_ flags, or 0
        @return: "" - could not decode instruction at the specified location
        @note: this function may not return exactly the same mnemonics
               as you see on the screen.
        """
        code = self.data[ea: + ea + self.MAX_BYTE_SIZE]
        instru = ""
        for (address, size, mnemonic, op_str) in self.capstone.disasm_lite(code, 0, 1):
            instru  = "%s %s" % (mnemonic, op_str)
            return instru
        else:
            return ""


# # flags for GetDisasmEx
# # generate a disassembly line as if
# # there is an instruction at 'ea'
# GENDSM_FORCE_CODE = ida_lines.GENDSM_FORCE_CODE

# # if the instruction consists of several lines,
# # produce all of them (useful for parallel instructions)
# GENDSM_MULTI_LINE = ida_lines.GENDSM_MULTI_LINE

    def GetDisasm(self,ea):
        """
        Get disassembly line
        @param ea: linear address of instruction
        @return: "" - could not decode instruction at the specified location
        @note: this function may not return exactly the same mnemonics
               as you see on the screen.
        """
        return self.GetDisasmEx(ea, 0)

    def GetMnem(self, ea):
        """
        Get instruction mnemonics
        @param ea: linear address of instruction
        @return: "" - no instruction at the specified location
        @note: this function may not return exactly the same mnemonics
        as you see on the screen.
        """
        code = self.data[ea:ea + self.MAX_BYTE_SIZE]
        for (address, size, mnemonic, op_str) in self.capstone.disasm_lite(code, 0, 1):
            if mnemonic:
                return mnemonic
            else:
                return ""


    def GetOpnd(self, ea, n):
        """
        Get operand of an instruction
        @param ea: linear address of instruction
        @param n: number of operand:
            0 - the first operand
            1 - the second operand
        @return: the current text representation of operand or ""
        """
        code = self.data[ea:ea + self.MAX_BYTE_SIZE]
        for instru in self.capstone.disasm(code, 0, 1):
            ops = instru.op_str
            if ops:
                if "," in ops:
                    temp = ops.split(",")
                    if 0 <= n < len(temp):
                        return temp[n].lstrip()
                else:
                    return ops
        return ""


cs = cs_db(b"\x48\x83\xEC\x28\xE8\x27\xF7\xFF\xFF\x48\x83\xC4\x28\xEB\x09\xCC", 64)
print cs.GetOpnd(4,0)
print cs.GetDisasm(4)
cs = cs_db(b"\x90", 64)
print cs.GetDisasm(0)

'''

    def GetOpType(self, ea, n):
        """
        Get type of instruction operand
        @param ea: linear address of instruction
        @param n: number of operand:
            0 - the first operand
            1 - the second operand
        @return: any of o_* constants or -1 on error
        """
        self.capstone.detail = True
        code = self.data[ea:ea + self.MAX_BYTE_SIZE]
        for instru in self.capstone.disasm(code, 0, 1):
            c = 0
            for i in instru.operands:
                if n == c:
                    return i.type
        return None 


o_void     = ida_ua.o_void      # No Operand                           ----------
o_reg      = ida_ua.o_reg       # General Register (al,ax,es,ds...)    reg
o_mem      = ida_ua.o_mem       # Direct Memory Reference  (DATA)      addr
o_phrase   = ida_ua.o_phrase    # Memory Ref [Base Reg + Index Reg]    phrase
o_displ    = ida_ua.o_displ     # Memory Reg [Base Reg + Index Reg + Displacement] phrase+addr
o_imm      = ida_ua.o_imm       # Immediate Value                      value
o_far      = ida_ua.o_far       # Immediate Far Address  (CODE)        addr
o_near     = ida_ua.o_near      # Immediate Near Address (CODE)        addr
o_idpspec0 = ida_ua.o_idpspec0  # Processor specific type
o_idpspec1 = ida_ua.o_idpspec1  # Processor specific type
o_idpspec2 = ida_ua.o_idpspec2  # Processor specific type
o_idpspec3 = ida_ua.o_idpspec3  # Processor specific type
o_idpspec4 = ida_ua.o_idpspec4  # Processor specific type
o_idpspec5 = ida_ua.o_idpspec5  # Processor specific type
                                # There can be more processor specific types

# x86
o_trreg  =       ida_ua.o_idpspec0      # trace register
o_dbreg  =       ida_ua.o_idpspec1      # debug register
o_crreg  =       ida_ua.o_idpspec2      # control register
o_fpreg  =       ida_ua.o_idpspec3      # floating point register
o_mmxreg  =      ida_ua.o_idpspec4      # mmx register
o_xmmreg  =      ida_ua.o_idpspec5      # xmm register



    def GetOperandValue(self, ea, n):
        """
        Get number used in the operand
        This function returns an immediate number used in the operand
        @param ea: linear address of instruction
        @param n: the operand number
        @return: value
            operand is an immediate value  => immediate value
            operand has a displacement     => displacement
            operand is a direct memory ref => memory address
            operand is a register          => register number
            operand is a register phrase   => phrase number
            otherwise                      => -1
        """
        inslen = ida_ua.decode_insn(ea)
        if inslen == 0:
            return -1
        op = ida_ua.cmd.Operands[n]
        if not op:
            return -1

        if op.type in [ ida_ua.o_mem, ida_ua.o_far, ida_ua.o_near, ida_ua.o_displ ]:
            value = op.addr
        elif op.type == ida_ua.o_reg:
            value = op.reg
        elif op.type == ida_ua.o_imm:
            value = op.value
        elif op.type == ida_ua.o_phrase:
            value = op.phrase
        else:
            value = -1
        return value


def LineA(ea, num):
    """
    Get anterior line
    @param ea: linear address
    @param num: number of anterior line (0..MAX_ITEM_LINES)
          MAX_ITEM_LINES is defined in IDA.CFG
    @return: anterior line string
    """
    return ida_lines.get_extra_cmt(ea, ida_lines.E_PREV + num)


def LineB(ea, num):
    """
    Get posterior line
    @param ea: linear address
    @param num: number of posterior line (0..MAX_ITEM_LINES)
    @return: posterior line string
    """
    return ida_lines.get_extra_cmt(ea, ida_lines.E_NEXT + num)


# def GetCommentEx(ea, repeatable):
    # """
    # Get regular indented comment
    # @param ea: linear address
    # @param repeatable: 1 to get the repeatable comment, 0 to get the normal comment
    # @return: string or None if it fails
    # """
    # return ida_bytes.get_cmt(ea, repeatable)


# def CommentEx(ea, repeatable):
    # """
    # Get regular indented comment
    # @param ea: linear address
    # @param repeatable: 1 to get the repeatable comment, 0 to get the normal comment
    # @return: string or None if it fails
    # """
    # return GetCommentEx(ea, repeatable)


# def AltOp(ea, n):
    # """
    # Get manually entered operand string
    # @param ea: linear address
    # @param n: number of operand:
         # 0 - the first operand
         # 1 - the second operand
    # @return: string or None if it fails
    # """
    # return ida_bytes.get_forced_operand(ea, n)

# ASCSTR_C       = ida_nalt.ASCSTR_TERMCHR # C-style ASCII string
# ASCSTR_PASCAL  = ida_nalt.ASCSTR_PASCAL  # Pascal-style ASCII string (length byte)
# ASCSTR_LEN2    = ida_nalt.ASCSTR_LEN2    # Pascal-style, length is 2 bytes
# ASCSTR_UNICODE = ida_nalt.ASCSTR_UNICODE # Unicode string
# ASCSTR_LEN4    = ida_nalt.ASCSTR_LEN4    # Pascal-style, length is 4 bytes
# ASCSTR_ULEN2   = ida_nalt.ASCSTR_ULEN2   # Pascal-style Unicode, length is 2 bytes
# ASCSTR_ULEN4   = ida_nalt.ASCSTR_ULEN4   # Pascal-style Unicode, length is 4 bytes
# ASCSTR_LAST    = ida_nalt.ASCSTR_LAST    # Last string type

# def GetString(ea, length = -1, strtype = ASCSTR_C):
    # """
    # Get string contents
    # @param ea: linear address
    # @param length: string length. -1 means to calculate the max string length
    # @param strtype: the string type (one of ASCSTR_... constants)
    # @return: string contents or empty string
    # """
    # if length == -1:
        # length = ida_bytes.get_max_ascii_length(ea, strtype, ida_bytes.ALOPT_IGNHEADS)

    # return ida_bytes.get_ascii_contents2(ea, length, strtype)


# def GetStringType(ea):
    # """
    # Get string type
    # @param ea: linear address
    # @return: One of ASCSTR_... constants
    # """
    # ti = ida_nalt.opinfo_t()

    # if ida_bytes.get_opinfo(ea, 0, GetFlags(ea), ti):
        # return ti.strtype
    # else:
        # return None

# #      The following functions search for the specified byte
# #          ea - address to start from
# #          flag is combination of the following bits

# #      returns BADADDR - not found
# def FindVoid        (ea, flag): return ida_search.find_void(ea, flag)
# def FindCode        (ea, flag): return ida_search.find_code(ea, flag)
# def FindData        (ea, flag): return ida_search.find_data(ea, flag)
# def FindUnexplored  (ea, flag): return ida_search.find_unknown(ea, flag)
# def FindExplored    (ea, flag): return ida_search.find_defined(ea, flag)
# def FindImmediate   (ea, flag, value): return ida_search.find_imm(ea, flag, value)

# SEARCH_UP       = ida_search.SEARCH_UP       # search backward
# SEARCH_DOWN     = ida_search.SEARCH_DOWN     # search forward
# SEARCH_NEXT     = ida_search.SEARCH_NEXT     # start the search at the next/prev item
                                             # # useful only for FindText() and FindBinary()
# SEARCH_CASE     = ida_search.SEARCH_CASE     # search case-sensitive
                                             # # (only for bin&txt search)
# SEARCH_REGEX    = ida_search.SEARCH_REGEX    # enable regular expressions (only for text)
# SEARCH_NOBRK    = ida_search.SEARCH_NOBRK    # don't test ctrl-break
# SEARCH_NOSHOW   = ida_search.SEARCH_NOSHOW   # don't display the search progress

def FindText(ea, flag, y, x, searchstr):
    """
    @param ea: start address
    @param flag: combination of SEARCH_* flags
    @param y: number of text line at ea to start from (0..MAX_ITEM_LINES)
    @param x: coordinate in this line
    @param searchstr: search string
    @return: ea of result or BADADDR if not found
    """
    return ida_search.find_text(ea, y, x, searchstr, flag)


def FindBinary(ea, flag, searchstr, radix=16):
    """
    @param ea: start address
    @param flag: combination of SEARCH_* flags
    @param searchstr: a string as a user enters it for Search Text in Core
    @param radix: radix of the numbers (default=16)
    @return: ea of result or BADADDR if not found
    @note: Example: "41 42" - find 2 bytes 41h,42h (radix is 16)
    """
    endea = flag & 1 and ida_ida.cvar.inf.maxEA or ida_ida.cvar.inf.minEA
    return ida_search.find_binary(ea, endea, searchstr, radix, flag)


#----------------------------------------------------------------------------
#                    C R O S S   R E F E R E N C E S
#----------------------------------------------------------------------------
#      Flow types (combine with XREF_USER!):
fl_CF   = 16              # Call Far
fl_CN   = 17              # Call Near
fl_JF   = 18              # Jump Far
fl_JN   = 19              # Jump Near
fl_F    = 21              # Ordinary flow

XREF_USER = 32            # All user-specified xref types
                          # must be combined with this bit


# Mark exec flow 'from' 'to'
def AddCodeXref(From, To, flowtype):
    """
    """
    return ida_xref.add_cref(From, To, flowtype)


def DelCodeXref(From, To, undef):
    """
    Unmark exec flow 'from' 'to'
    @param undef: make 'To' undefined if no more references to it
    @returns: 1 - planned to be made undefined
    """
    return ida_xref.del_cref(From, To, undef)


# The following functions include the ordinary flows:
# (the ordinary flow references are returned first)
def Rfirst(From):
    """
    Get first code xref from 'From'
    """
    return ida_xref.get_first_cref_from(From)


def Rnext(From, current):
    """
    Get next code xref from
    """
    return ida_xref.get_next_cref_from(From, current)


def RfirstB(To):
    """
    Get first code xref to 'To'
    """
    return ida_xref.get_first_cref_to(To)


def RnextB(To, current):
    """
    Get next code xref to 'To'
    """
    return ida_xref.get_next_cref_to(To, current)


# The following functions don't take into account the ordinary flows:
def Rfirst0(From):
    """
    Get first xref from 'From'
    """
    return ida_xref.get_first_fcref_from(From)


def Rnext0(From, current):
    """
    Get next xref from
    """
    return ida_xref.get_next_fcref_from(From, current)


def RfirstB0(To):
    """
    Get first xref to 'To'
    """
    return ida_xref.get_first_fcref_to(To)


def RnextB0(To, current):
    """
    Get next xref to 'To'
    """
    return ida_xref.get_next_fcref_to(To, current)


# Data reference types (combine with XREF_USER!):
dr_O    = ida_xref.dr_O  # Offset
dr_W    = ida_xref.dr_W  # Write
dr_R    = ida_xref.dr_R  # Read
dr_T    = ida_xref.dr_T  # Text (names in manual operands)
dr_I    = ida_xref.dr_I  # Informational


def add_dref(From, To, drefType):
    """
    Create Data Ref
    """
    return ida_xref.add_dref(From, To, drefType)


def del_dref(From, To):
    """
    Unmark Data Ref
    """
    return ida_xref.del_dref(From, To)


def Dfirst(From):
    """
    Get first data xref from 'From'
    """
    return ida_xref.get_first_dref_from(From)


def Dnext(From, current):
    """
    Get next data xref from 'From'
    """
    return ida_xref.get_next_dref_from(From, current)


def DfirstB(To):
    """
    Get first data xref to 'To'
    """
    return ida_xref.get_first_dref_to(To)


def DnextB(To, current):
    """
    Get next data xref to 'To'
    """
    return ida_xref.get_next_dref_to(To, current)


def XrefType():
    """
    Return type of the last xref obtained by
    [RD]first/next[B0] functions.
    @return: constants fl_* or dr_*
    """
raise DeprecatedIDCError, "use XrefsFrom() XrefsTo() from idautils instead."
'''

Comments (0)

HTTPS SSH

You can clone a snippet to your computer for local editing. Learn more.