⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 optab.pl

📁 It s a Linux disassemble, can set break point, disassemble ELF file.
💻 PL
字号:
#!/usr/bin/perl## optab.pl# Generate source/include files from input file optab-x86.dat## Note: this script sets up the assembler/disassembler files# in similar manner to NASM. However, because of NASM's# restricted licensing, I was forced to "reinvent the wheel"# so to speak. As a result, the overall idea of how this# works is similar to NASM, but the actual implementation# is different.## $Id: optab.pl,v 1.1.1.1 2004/04/26 00:40:21 pa33 Exp $$InputFile = "optab-x86.dat";$SourceOutputFileD = "dtab-x86.c";$SourceOutputFileA = "atab-x86.c";$IncludeOutputFileN = "inames-x86.h";$IncludeOutputFile = "optab-x86.h";open (INFILE, $InputFile) || die "Unable to open $InputFile";# Current line number$linenum = 0;# Offset in our opcode array$offset = 0;while (<INFILE>){  $linenum++;  # skip comments  next if /^\s*#/;  # Remove newlines  chomp;  # Split line into substrings  split;  # skip blank lines  next if $#_ == -1;  # Make sure there are at least three fields in the line  if ($#_ < 2)  {    warn "Line $linenum contains less than three fields\n";    next;  }  # Format the line - convert intel syntax to our bitmask names  # etc  ($FormattedLine) = &format(@_);  if ($FormattedLine)  {    ## print "format = $FormattedLine\n";    ## print "0 = $_[0], 1 = $_[1], 2 = $_[2] 3 = $_[3]\n";    $CodeName = "Code_$_[0]";    push @$CodeName, $FormattedLine;    # Our opcodes are stored as two digits separated by    # commas (XX,YY,ZZ), so extract the first byte of the    # opcode, and store it in our Op array    $ii = substr($_[2], 0, 2);    $CodeName = "Op_$ii";    push @$CodeName, $offset;  }  $oparray{$_[0]}++;  $offset++;}close INFILE;@opcodes = sort keys(%oparray);# Generate assembly table fileprint STDERR "Generating ../source/$SourceOutputFileA\n";open (OUTFILE, ">../source/$SourceOutputFileA") ||  die "Unable to open ../source/$SourceOutputFileA";print OUTFILE "/*\n";print OUTFILE " * This file was generated by optab.pl - do not edit.\n";print OUTFILE " */\n\n";print OUTFILE "#include \"common-x86.h\"\n";print OUTFILE "#include \"operands-x86.h\"\n";print OUTFILE "#include \"optab-x86.h\"\n";print OUTFILE "#include \"regs-x86.h\"\n";print OUTFILE "\n";foreach $ii (@opcodes){  print OUTFILE "static struct x86OpCode Instruction_${ii}[] = {\n";  $CodeName = "Code_${ii}";  foreach $jj (@$CodeName)  {    print OUTFILE "  $jj\n";  }  print OUTFILE "  { -1, -1, { -1, -1, -1 }, 0, -1, -1, { -1, -1, -1 } }\n};\n\n";}print OUTFILE "struct x86OpCode *x86Instructions[] = {";$first = 1;foreach $ii (@opcodes){  if (!$first) { print OUTFILE ","; } else { $first = 0; }  print OUTFILE "\n  Instruction_${ii}";}print OUTFILE "\n};\n";close OUTFILE;# Generate disassembly table fileprint STDERR "Generating ../source/$SourceOutputFileD\n";open (OUTFILE, ">../source/$SourceOutputFileD") ||  die "Unable to open ../source/$SourceOutputFileD";print OUTFILE "/*\n";print OUTFILE " * This file was generated by optab.pl - do not edit.\n";print OUTFILE " */\n\n";print OUTFILE "#include \"common-x86.h\"\n";print OUTFILE "#include \"operands-x86.h\"\n";print OUTFILE "#include \"$IncludeOutputFile\"\n";print OUTFILE "#include \"regs-x86.h\"\n";print OUTFILE "\nstatic struct x86OpCode Instructions[] = {\n";foreach $ii (@opcodes){  $CodeName = "Code_$ii";  foreach $jj (@$CodeName)  {    print OUTFILE "  $jj\n";  }}print OUTFILE "  { 0, 0, { 0, 0, 0 }, 0, 0, 0, { 0, 0, 0 } }\n";print OUTFILE "};\n\n";for ($c = 0; $c < 256; $c++){  $h = sprintf "%02X", $c;  print OUTFILE "static struct x86OpCode *OpCode_${h}[] = {\n";  $CodeName = "Op_$h";  foreach $jj (@$CodeName)  {    print OUTFILE "  Instructions + $jj,\n";  }  print OUTFILE "  0\n};\n\n";}print OUTFILE "struct x86OpCode **x86OpCodes[] = {\n";for ($c = 0; $c < 256; $c++){  printf OUTFILE "  OpCode_%02X,\n", $c;}print OUTFILE "};\n";close OUTFILE;print STDERR "Generating ../include/$IncludeOutputFileN\n";open (OUTFILE, ">../include/$IncludeOutputFileN") ||  die "Unable to open ../include/$IncludeOutputFileN";print OUTFILE "/*\n";print OUTFILE " * This file was generated by optab.pl - do not edit.\n";print OUTFILE " */\n\n";print OUTFILE "#ifndef INCLUDED_inames_x86_h\n";print OUTFILE "#define INCLUDED_inames_x86_h\n\n";print OUTFILE "static const char *x86InstructionNames[] = {";$first = 1;foreach $ii (@opcodes){  if (!$first) { print OUTFILE ","; } else { $first = 0; }  $lower = $ii;  $lower =~ tr/A-Z/a-z/;  #print OUTFILE "  \"$lower\",\n";  print OUTFILE "\n  \"$lower\"";}print OUTFILE "\n};\n";print OUTFILE "\n#endif /* INCLUDED_inames_x86_h */\n";close OUTFILE;print STDERR "Generating ../include/$IncludeOutputFile\n";open (OUTFILE, ">../include/$IncludeOutputFile") ||  die "Unable to open ../include/$IncludeOutputFile";print OUTFILE "/*\n";print OUTFILE " * This file was generated by optab.pl - do not edit.\n";print OUTFILE " */\n\n";print OUTFILE "#ifndef INCLUDED_optab_x86_h\n";print OUTFILE "#define INCLUDED_optab_x86_h\n\n";print OUTFILE "enum\n{\n";print OUTFILE join(",\n", map { "  I_$_" } @opcodes), "\n";print OUTFILE "};\n";print OUTFILE "\n";print OUTFILE "extern struct x86OpCode **x86OpCodes[];\n";print OUTFILE "extern struct x86OpCode *x86Instructions[];\n";#print OUTFILE "extern const char *x86InstructionNames[];\n";print OUTFILE "\n#endif /* INCLUDED_optab_x86_h */\n";close OUTFILE;# This function takes an array of strings as input, formats# them, and returns an array entry for our Instructions[]# array.## Inputs: arg1 - instruction name#         arg2 - list of operands separated by commas#         arg3 - list of opcode bytes separated by commas#         arg4 - (optional) additional info such as modrm valuessub format{  local ($inst, $operands, $codes, $modrm) = @_;  local $opcnt = 0;  local $oparg1 = "-1";  local $oparg2 = "-1";  local $oparg3 = "-1";  # format the operands  $operands =~ s/fpureg/reg_fpu/g;  $operands =~ s/imm(\d+)/imm|bits$1/g;  $operands =~ s/imm/immediate/g;  $operands =~ s/mem(\d+)/mem|bits$1/g;  $operands =~ s/mem/memory/g;  $operands =~ s/mmxreg/reg_mmx/g;  $operands =~ s/moffs/memoffs/g;  $operands =~ s/rel(\d+)/relative|bits$1/g;  $operands =~ s/rm(\d+)/regmem|bits$1/g;  $operands =~ s/segreg/reg_sr/g;  $operands =~ s/xmmreg/reg_xmm/g;  $operands =~ s/conreg/reg_control/g;  $operands =~ s/debreg/reg_debug/g;  $operands =~ s/ptr(\d+):(\d+)/seg$1|off$2/g;  if ($operands !~ /_rm/) { $operands =~ s/rm/regmem/g; }  # Add a BITS32 to OFF32 opcodes so they will get priority over  # their 16 bit versions, if any  $operands =~ s/off32/off32|bits32/g;  # Handle rDD(xxx) situations  ($op1, $op2, $op3) = split(/,/, $operands, 3);  if ($op1 =~ s/r(\d+)\((\w+)\)/register|bits$1/g) { $oparg1 = "r_$2"; }  if ($op1 =~ s/r\((\w+)\)/register/g) { $oparg1 = "r_$1"; }  if ($op1 =~ s/const(\d+)/constant/g) { $oparg1 = $1; }  if ($op1 =~ s/reg(\d+)_rm/reg$1/g) { $oparg1 = "MODFIELD_RM"; }  if ($op2 =~ s/r(\d+)\((\w+)\)/register|bits$1/g) { $oparg2 = "r_$2"; }  if ($op2 =~ s/r\((\w+)\)/register/g) { $oparg2 = "r_$1"; }  if ($op2 =~ s/const(\d+)/constant/g) { $oparg2 = $1; }  if ($op2 =~ s/reg(\d+)_rm/reg$1/g) { $oparg2 = "MODFIELD_RM"; }  if ($op3 =~ s/r(\d+)\((\w+)\)/register|bits$1/g) { $oparg3 = "r_$2"; }  if ($op3 =~ s/r\((\w+)\)/register/g) { $oparg3 = "r_$1"; }  if ($op3 =~ s/const(\d+)/constant/g) { $oparg3 = $1; }  if ($op3 =~ s/reg(\d+)_rm/reg$1/g) { $oparg3 = "MODFIELD_RM"; }  if (length($op3) != 0)  {    $opcnt = 3;    $finalop = "$op1, $op2, $op3";  }  elsif (length($op2) != 0)  {    $opcnt = 2;    $finalop = "$op1, $op2, 0";  }  elsif (length($op1) != 0)  {    $opcnt = 1;    $finalop = "$op1, 0, 0";  }  else  {    $opcnt = 0;    $finalop = "0, 0, 0";  }  $finalop = '0, 0, 0', $opcnt = 0 if $operands eq 'void';  $finalop = 'BITS32, 0, 0', $opcnt = 0 if $operands eq 'void32';  $finalop =~ tr/a-z/A-Z/;  # We must convert opargs to uppercase in case they hold  # a register index (ie: r_al -> R_AL)  $oparg1 =~ tr/a-z/A-Z/;  $oparg2 =~ tr/a-z/A-Z/;  $oparg3 =~ tr/a-z/A-Z/;  # codes will come in looking something like: F1,F2,F3  # Replace the commas with a \x and stick a \x on the front  # to get the first opcode (\xF1\xF2\xF3)  $oplen = $codes =~ tr/\,/\,/;  $oplen++;  $codes =~ s/\,/\\x/g;  $codes = "\\x" . $codes;  # If there is no digit associated with the opcode, make the field  # -1. If the digit is /r, make the field "REGRM", otherwise it's  # numerical value. A value of "c" indicates a register code  # that is added to the opcode.  $modrm = -1 if $modrm eq '';  $modrm = 'REGRM' if $modrm eq 'r';  $modrm = 'REGCODE' if $modrm eq 'c';  $modrm = 'FPUCODE' if $modrm eq 'f';  ("{ I_$inst, $opcnt, { $finalop }, \"$codes\", $oplen, $modrm, { $oparg1, $oparg2, $oparg3 } },");}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -