jcunews

NDebug.vbs

May 1st, 2020 (edited)
640
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VBScript 16.67 KB | None | 0 0
  1. 'NDebug v1.0.2. Is Not a Debugger.
  2. 'https://pastebin.com/u/jcunews
  3. 'https://www.reddit.com/user/jcunews1
  4. '
  5. 'DOS DEBUG clone mainly for binary file editing (as a hex editor).
  6. '
  7. 'Differences:
  8. '- No disassembler and assembler functions.
  9. '- No executable program/code.
  10. '- No disk sector, I/O port, and expanded memory (EMS).
  11. '- No CPU flag register, and CPU/FPU mode.
  12. '- Memory is simulated using zero filled buffer.
  13. '- CPU registers are simulated.
  14. '- Default segment for loading file is 0000.
  15. '- E command's list parameter is required.
  16. '- L command accepts file name as third parameter.
  17. '- Support file size up to 256MB.
  18. '
  19. 'Effective CPU registers:
  20. '- CS:IP = Starting address of file for L & W commands
  21. '- BX:CX = Size of file for L & W commands
  22. '- DS    = Default segment for C, D, E, F, M, and S commands.
  23. '- SI    = Number of 1MB memory storages. From 2 up to 256. Default is 2.
  24. '- DI    = Index of memory storage. Default is 0. i.e.:
  25. '          DI:DS:AX = 001 1234:5678 = 1 179B8 = linear address 1179B8.
  26. '
  27. 'Usage: NDebug.vbs [file]
  28. '
  29. 'For a list of commands, run script and type ? at the prompt.
  30.  
  31. 'Debug help screen
  32. 'compare      C range address
  33. 'dump         D [range]
  34. 'enter        E address list
  35. 'fill         F range list
  36. 'hex add/sub  H value1 value2
  37. 'load file    L [address [[path]filename]]
  38. 'move         M range address
  39. 'set name     N [path]filename
  40. 'quit         Q
  41. 'register     R [register [value]]
  42. 'search       S range list
  43. 'write file   W [address]
  44. 'range: address [l length | offset]
  45. 'address: [segment:]offset
  46. 'list: byte[,byte..] | "string"[ "string"...]
  47. 'value: word
  48.  
  49. function hexb(n)
  50.   a = "0" & hex(n)
  51.   hexb = right(a, 2)
  52. end function
  53.  
  54. function hexw(n)
  55.   a = "000" & hex(n)
  56.   hexw = right(a, 4)
  57. end function
  58.  
  59. function loadfile(seg, ofs, fn)
  60.   on error resume next
  61.   a = clng(int(((seg * 65536) + ofs + fs.getfile(fn).size + 65535) / 65536))
  62.   loadfile = err.number = 0
  63.   if not loadfile then exit function
  64.   if a > (ubound(mem) + 1) then
  65.     if not resizemem(a) then
  66.       writeln "Insufficient memory"
  67.       loadfile = false
  68.       exit function
  69.     end if
  70.   end if
  71.   st.type = 2
  72.   st.charset = "x-user-defined"
  73.   st.open
  74.   st.loadfromfile fn
  75.   if err.number = 0 then
  76.     a = st.readtext
  77.     writemems seg, ofs, a
  78.     bx = clng(int(len(a) / 65536))
  79.     cx = len(a) and 65535
  80.     loadfile = true
  81.   end if
  82.   st.close
  83. end function
  84.  
  85. function parseaddr(byref ms, mi, reqofs, defseg, defofs, byref seg, byref ofs)
  86.   parseaddr = true
  87.   if ms(mi) <> "" then 'number: segment
  88.    seg = str2intw(ms(mi))
  89.   elseif ms(mi + 1) <> "" then 'register: segment
  90.    seg = eval(ms(mi + 1))
  91.   else
  92.     seg = defseg
  93.   end if
  94.   if ms(mi + 2) <> "" then 'number: offset
  95.    ofs = str2intw(ms(mi + 2))
  96.   elseif ms(mi + 3) <> "" then 'register: offset
  97.    ofs = eval(ms(mi + 3))
  98.   elseif reqofs then
  99.     parseaddr = false
  100.   else
  101.     ofs = defofs
  102.   end if
  103. end function
  104.  
  105. function parselist(ofs, s, byref data)
  106.   if s = "" then
  107.     parselist = true
  108.     exit function
  109.   end if
  110.   parselist = true
  111.   set y = new regexp
  112.   y.pattern = "\s*([0-9a-f]{1,2}|""[^""]+"")"
  113.   c = s
  114.   data = ""
  115.   f = ofs
  116.   do while c <> ""
  117.     set m = y.execute(c)
  118.     if m.count = 0 then
  119.       parselist = false
  120.       exit function
  121.     end if
  122.     e = m(0).submatches(0)
  123.     if left(e, 1) <> """" then
  124.       data = data & chr(str2intb(e)) 'byte
  125.      f = f + 1
  126.     else
  127.       g = mid(e, 2, len(e) - 2)
  128.       data = data & g 'string
  129.      f = f + len(g)
  130.     end if
  131.     if f > 65535 then
  132.       parselist = false
  133.       exit function
  134.     end if
  135.     c = mid(c, m(0).length + 1)
  136.   loop
  137. end function
  138.  
  139. function parserange(byref ms, mi, reqofs, reqlen, clip, defseg, defofs, _
  140.   deflen, byref seg, byref ofs, byref last)
  141.   parserange = parseaddr(ms, mi, reqofs, defseg, defofs, seg, ofs)
  142.   if not parserange then exit function
  143.   if ms(mi + 4) <> "" then 'number: length
  144.    last = ofs + str2intw(ms(mi + 4)) - 1
  145.   elseif ms(mi + 5) <> "" then 'register: length
  146.    last = ofs + eval(ms(mi + 5)) - 1
  147.   elseif ms(mi + 6) <> "" then 'number: end offset
  148.    last = str2intw(ms(mi + 6))
  149.   elseif ms(mi + 7) <> "" then 'register: end offset
  150.    last = eval(ms(mi + 7))
  151.   elseif reqlen then
  152.     parserange = false
  153.     exit function
  154.   else
  155.     last = ofs + deflen - 1
  156.   end if
  157.   if clip then
  158.     if last > 65535 then last = 65535
  159.   else
  160.     parserange = last <= 65535
  161.   end if
  162. end function
  163.  
  164. function readln
  165.   on error resume next
  166.   do while true
  167.     readln = wscript.stdin.readline
  168.     if err.number = 0 then exit do
  169.     err.clear
  170.   loop
  171. end function
  172.  
  173. function readmemb(cs, ip)
  174.   a = segofs2memadr(cs, ip)
  175.   readmemb = mid(mem((di * 16) + a(0)), a(1) + 1, 1)
  176. end function
  177.  
  178. function readmems(seg, ofs, length)
  179.   a = (di * 16) + clng(int(seg / 4096))
  180.   b = ((seg and &Hfff) * &H10) + ofs
  181.   i = 0
  182.   r = ""
  183.   do while i < length
  184.     c = length - i
  185.     if (b + c) > 65536 then c = 65536 - b
  186.     r = r & mid(mem(a), b + 1, c)
  187.     a = a + 1
  188.     b = 0
  189.     i = i + c
  190.   loop
  191.   readmems = r
  192. end function
  193.  
  194. function resizemem(n)
  195.   resizemem = (n * 65536) <= maxmem
  196.   if not resizemem then exit function
  197.   a = ubound(mem)
  198.   redim preserve mem(n)
  199.   if n > a then
  200.     for i = a + 1 to ubound(mem)
  201.       mem(i) = string(65536, chr(0))
  202.     next
  203.   end if
  204. end function
  205.  
  206. function segofs(a, b)
  207.   segofs = hexw(a) & ":" & hexw(b)
  208. end function
  209.  
  210. function segofs2memadr(seg, ofs)
  211.   a = (seg * &H10) + ofs
  212.   segofs2memadr = array(clng(int(a / 65536)), a and 65535)
  213. end function
  214.  
  215. function str2intb(a)
  216.   str2intb = eval("&H" & a) and 255
  217. end function
  218.  
  219. function str2intw(a)
  220.   str2intw = eval("&H" & a) and 65535
  221. end function
  222.  
  223. sub write(s)
  224.   wscript.stdout.write s
  225. end sub
  226.  
  227. sub writeln(s)
  228.   wscript.stdout.writeline s
  229. end sub
  230.  
  231. sub writememb(seg, ofs, n)
  232.   a = (di * 16) + clng(int(seg / 4096))
  233.   b = ((seg and &Hfff) * &H10) + ofs
  234.   mem(a) = mid(mem(a), 1, b) & chr(n) & mid(mem(a), b + 2)
  235. end sub
  236.  
  237. sub writemems(seg, ofs, data)
  238.   a = (di * 16) + clng(int(seg / 4096))
  239.   b = ((seg and &Hfff) * &H10) + ofs
  240.   i = 0
  241.   do while i <= (len(data) - 1)
  242.     c = len(data) - i
  243.     if (b + c) > 65536 then c = 65536 - b
  244.     mem(a) = mid(mem(a), 1, b) & mid(data, i + 1, c) & mid(mem(a), b + c + 1)
  245.     a = a + 1
  246.     b = 0
  247.     i = i + c
  248.   loop
  249. end sub
  250.  
  251. '--------------------------------------------------------------------
  252.  
  253. sub compare
  254.   x.pattern = "^c\s*" & xrng & "\s+" & xaddr & "\s*$" '8+4
  255.  set m = x.execute(cl)
  256.   if m.count > 0 then
  257.     set m = m(0).submatches
  258.     if not parserange(m, 0, true, true, false, ds, 0, 0, a, b, c) then
  259.       writeln "Error"
  260.       exit sub
  261.     end if
  262.     d = (c + 1) - b 'length
  263.    parseaddr m, 8, true, ds, 0, e, f
  264.     if (c < b) or ((65536 - f) < d) then
  265.       writeln "Error"
  266.       exit sub
  267.     end if
  268.     do while d > 0
  269.       g = 65536 - b
  270.       h = 65536 - f
  271.       if h < g then g = h
  272.       h = readmems(a, b, g)
  273.       i = readmems(e, f, g)
  274.       for j = 1 to len(h)
  275.         k = mid(h, j, 1)
  276.         l = mid(i, j, 1)
  277.         if k <> l then
  278.           writeln segofs(a, b + j - 1) & "  " & hexb(asc(k)) & "  " & _
  279.             hexb(asc(l)) & "  " & segofs(e, f + j - 1)
  280.         end if
  281.       next
  282.       b = b + g
  283.       if b = 0 then a = a + &H1000
  284.       f = f + g
  285.       if f = 0 then e = e + &H1000
  286.       d = d - g
  287.     loop
  288.   else
  289.     writeln "Error"
  290.   end if
  291. end sub
  292.  
  293. sub dump
  294.   x.pattern = "^d\s*(?:" & xrng & "?)?\s*$" '8
  295.  set m = x.execute(cl)
  296.   if m.count > 0 then
  297.     set m = m(0).submatches
  298.     parserange m, 0, false, false, true, dg, df, &H80, k, a, b
  299.     if (b < a) or (b > 65535) then
  300.       writeln "Error"
  301.       exit sub
  302.     end if
  303.     j = b and &Hfff0
  304.     c = a and &Hfff0
  305.     d = a and &Hf
  306.     do while c <= b
  307.       write segofs(k, c) & "  "
  308.       e = " "
  309.       if c <> j then
  310.         f = &Hf
  311.       else
  312.         f = b and &Hf
  313.       end if
  314.       for i = 0 to &Hf
  315.         if (i >= d) and (i <= f) then
  316.           g = readmemb(k, c + i)
  317.           h = asc(g)
  318.           if (h < &H20) or (h > &H7e) then g = "."
  319.           write hexb(h)
  320.         else
  321.           g = " "
  322.           write "  "
  323.         end if
  324.         e = e & g
  325.         if i = 7 then
  326.           write "-"
  327.         else
  328.           write " "
  329.         end if
  330.       next
  331.       writeln e
  332.       d = 0
  333.       c = c + 16
  334.     loop
  335.     dg = k
  336.     df = (b + 1) and 65535
  337.   else
  338.     writeln "Error"
  339.   end if
  340. end sub
  341.  
  342. sub enter
  343.   x.pattern = "^e\s*" & xaddr & "(.*?)\s*$" '4+1
  344.  set m = x.execute(cl)
  345.   if m.count > 0 then
  346.     set m = m(0).submatches
  347.     parseaddr m, 0, true, ds, 0, a, b
  348.     if not parselist(b, m(4), d) then
  349.       writeln "Error"
  350.       exit sub
  351.     end if
  352.     writemems a, b, d
  353.   else
  354.     writeln "Error"
  355.   end if
  356. end sub
  357.  
  358. sub fill
  359.   x.pattern = "^f\s*" & xrng & "(.*?)\s*$" '8+1
  360.  set m = x.execute(cl)
  361.   if m.count > 0 then
  362.     set m = m(0).submatches
  363.     if not parserange(m, 0, true, true, false, ds, 0, 0, a, b, c) then
  364.       writeln "Error"
  365.       exit sub
  366.     end if
  367.     if not parselist(b, m(8), d) then
  368.       writeln "Error"
  369.       exit sub
  370.     end if
  371.     do while b < c
  372.       if (b + len(d)) > c then d = left(d, c - b)
  373.       writemems a, b, d
  374.       b = b + len(d)
  375.     loop
  376.   else
  377.     writeln "Error"
  378.   end if
  379. end sub
  380.  
  381. sub help
  382.   set sf = fs.opentextfile(wscript.scriptfullname)
  383.   s = " "
  384.   do while s <> ""
  385.     s = sf.readline
  386.   loop
  387.   i = 0
  388.   do while true
  389.     s = sf.readline
  390.     if s = "" then exit sub
  391.     writeln mid(s, 2)
  392.     i = i + 1
  393.     if i = 23 then
  394.       i = 0
  395.       write "[press ENTER for more]"
  396.       readln
  397.       write chr(13) & space(22) & chr(13)
  398.     end if
  399.   loop
  400. end sub
  401.  
  402. sub hexCalc
  403.   x.pattern = "^h\s*" & xval & "\s+" & xval & "\s*$" '1+1
  404.  set m = x.execute(cl)
  405.   if m.count > 0 then
  406.     set m = m(0).submatches
  407.     a = str2intw(m(0))
  408.     b = str2intw(m(1))
  409.     writeln hexw(a + b) & " " & hexw(a - b)
  410.   else
  411.     writeln "Error"
  412.   end if
  413. end sub
  414.  
  415. sub load
  416.   x.pattern = "^l\s*(?:" & xaddr & "(?:\s*(.*?))?)?\s*$" '4+1
  417.  set m = x.execute(cl)
  418.   if m.count > 0 then
  419.     set m = m(0).submatches
  420.     parseaddr m, 0, false, 0, &H100, a, b
  421.     if m(4) <> "" then 'file
  422.      c = m(4)
  423.       if left(c, 1) = """" then
  424.         if right(c, 1) = """" then
  425.           c = trim(mid(c, 2, len(c) - 2))
  426.         else
  427.           c = ltrim(mid(c, 2))
  428.         end if
  429.       end if
  430.     else
  431.       c = fp
  432.     end if
  433.     if loadfile(a, b, c) then
  434.       fp = c
  435.     else
  436.       writeln "File not found"
  437.     end if
  438.   else
  439.     writeln "Error"
  440.   end if
  441. end sub
  442.  
  443. sub move
  444.   x.pattern = "^m\s*" & xrng & "\s+" & xaddr & "\s*$" '8+4
  445.  set m = x.execute(cl)
  446.   if m.count > 0 then
  447.     set m = m(0).submatches
  448.     if not parserange(m, 0, true, true, false, ds, 0, 0, a, b, c) then
  449.       writeln "Error"
  450.       exit sub
  451.     end if
  452.     d = (c + 1) - b 'length
  453.    parseaddr m, 8, true, ds, 0, e, f
  454.     if (c < b) or ((65536 - f) < d) then
  455.       writeln "Error"
  456.       exit sub
  457.     end if
  458.     writemems e, f, readmems(a, b, c - b + 1)
  459.   else
  460.     writeln "Error"
  461.   end if
  462. end sub
  463.  
  464. sub name
  465.   a = ltrim(mid(cl, 2))
  466.   if left(a, 1) = """" then
  467.     if right(a, 1) = """" then
  468.       a = trim(mid(a, 2, len(a) - 2))
  469.     else
  470.       a = ltrim(mid(a, 2))
  471.     end if
  472.   end if
  473.   fp = a
  474. end sub
  475.  
  476. sub register
  477.   x.pattern = "^r\s*(?:" & xregs & "(?:\s+" & xvlrg & ")?)?\s*$" '1+2
  478.  set m = x.execute(cl)
  479.   if m.count > 0 then
  480.     set m = m(0).submatches
  481.     if m(0) <> "" then 'set registers
  482.      a = ucase(m(0))
  483.       if a = "SI" then
  484.         tsi = si
  485.       elseif a = "DI" then
  486.         tdi = di
  487.       end if
  488.       if m(1) <> "" then 'immediate number
  489.        b = str2intw(m(1))
  490.         if isempty(b) then
  491.           writeln "Error"
  492.           exit sub
  493.         end if
  494.         executeglobal a & "=" & b
  495.       elseif m(2) <> "" then 'immediate register
  496.        b = eval(m(2))
  497.         if isempty(b) then
  498.           writeln "Error"
  499.           exit sub
  500.         end if
  501.         executeglobal a & "=" & b
  502.       else 'prompt
  503.        b = eval(a)
  504.         write a & " " & hexw(b) & "  :"
  505.         b = trim(readln)
  506.         if b = "" then exit sub
  507.         y.pattern = "^" & xvlrg & "$"
  508.         set m = y.execute(b)
  509.         if m.count > 0 then
  510.           set m = m(0).submatches
  511.           if m(0) <> "" then 'number
  512.            b = str2intw(b)
  513.           else 'register
  514.            b = eval(b)
  515.           end if
  516.         else
  517.           writeln "Error"
  518.           exit sub
  519.         end if
  520.         executeglobal a & "=" & b
  521.       end if
  522.       if a = "SI" then
  523.         if si <> tsi then
  524.           if (si > 0) and (si <= int(maxmem / 1048576)) then
  525.             resizemem si
  526.           else
  527.             si = tsi
  528.             writeln "Error"
  529.           end if
  530.         end if
  531.       elseif a = "DI" then
  532.         if di <> tdi then
  533.           if di > (int((ubound(mem) + 1) / 16) - 1) then
  534.             di = tdi
  535.             writeln "Error"
  536.           end if
  537.         end if
  538.       end if
  539.     else 'display registers
  540.      writeln "AX=" & hexw(ax) & " BX=" & hexw(bx) & " CX=" & hexw(cx) & _
  541.         " DX=" & hexw(dx) & " SP=" & hexw(sp) & " BP=" & hexw(bp) & _
  542.         " SI=" & hexw(si) & " DI=" & hexw(di) & vbcrlf & "DS=" & hexw(ds) & _
  543.         " ES=" & hexw(es) & " SS=" & hexw(ss) & " CS=" & hexw(cs) & _
  544.         " IP=" & hexw(ip)
  545.     end if
  546.   else
  547.     writeln "Error"
  548.   end if
  549. end sub
  550.  
  551. sub search
  552.   x.pattern = "^s\s*" & xrng & "(.*?)\s*$" '8+1
  553.  set m = x.execute(cl)
  554.   if m.count > 0 then
  555.     set m = m(0).submatches
  556.     if not parserange(m, 0, true, true, false, ds, 0, 0, a, b, c) then
  557.       writeln "Error"
  558.       exit sub
  559.     end if
  560.     if not parselist(b, m(8), d) then
  561.       writeln "Error"
  562.       exit sub
  563.     end if
  564.     c = c - len(d) + 1
  565.     do while b < c
  566.       if readmems(a, b, len(d)) = d then
  567.         writeln segofs(a, b)
  568.       end if
  569.       b = b + 1
  570.     loop
  571.   else
  572.     writeln "Error"
  573.   end if
  574. end sub
  575.  
  576. sub writefile
  577.   x.pattern = "^w\s*(?:" & xaddr & "(?:\s*(.*?))?)?\s*$" '4+1
  578.  set m = x.execute(cl)
  579.   if m.count > 0 then
  580.     set m = m(0).submatches
  581.     parseaddr m, 0, false, 0, &H100, a, b
  582.     c = (bx * 65536) + cx
  583.     d = (a * &H10) + b + c
  584.     if d > ((ubound(mem) + 1) * 65536) then
  585.       writeln "Error"
  586.       exit sub
  587.     end if
  588.     st.type = 2
  589.     st.charset = "x-user-defined"
  590.     st.open
  591.     st.writetext readmems(a, b, c)
  592.     on error resume next
  593.     st.savetofile fp, 2
  594.     if err.number = 0 then
  595.       d = hex(c)
  596.       if len(d) < 4 then d = string(4 - len(d), "0") & d
  597.       writeln "Writing " & d & " bytes"
  598.     else
  599.       writeln "File not found"
  600.     end if
  601.     st.close
  602.   else
  603.     writeln "Error"
  604.   end if
  605. end sub
  606.  
  607. '====================================================================
  608.  
  609. if wscript.arguments.count > 0 then
  610.   fp = wscript.arguments(0)
  611. else
  612.   fp = ""
  613. end if
  614. set fs = createobject("scripting.filesystemobject")
  615. if fp <> "" then
  616.   if left(fp, 1) = "/" then
  617.     if fp = "/?" then
  618.       set sf = fs.opentextfile(wscript.scriptfullname)
  619.       do while true
  620.         s = sf.readline
  621.         if s = "" then wscript.quit
  622.         writeln mid(s, 2)
  623.       loop
  624.     else
  625.       writeln "Invalid switch - " & mid(fp, 2, 1)
  626.     end if
  627.     wscript.quit
  628.   end if
  629. end if
  630. set st = createobject("adodb.stream")
  631.  
  632. ax = 0
  633. bx = 0 'file write length high
  634. cx = 0 'file write length low
  635. dx = 0
  636. sp = 0
  637. bp = 0
  638. si = 2 'memory bank size. 1mb each
  639. di = 0 'memory bank index
  640. ds = 0 'data segment
  641. es = 0
  642. ss = 0
  643. cs = 0 'file segment
  644. ip = &H100 'file offset
  645. dg = ds 'dump segment context
  646. df = ip 'dump offset context
  647. maxmem = 256 * 1048576 'max memory storage in bytes
  648. redim mem(-1)
  649. resizemem si * 16 - 1 'memory storage in 64kb blocks. min & default is 1mb+64k
  650.  
  651. if fp <> "" then
  652.   if fs.fileexists(fp) then
  653.     loadfile cs, ip, fp
  654.   else
  655.     writeln "File not found"
  656.   end if
  657. end if
  658.  
  659. set x = new regexp
  660. x.ignorecase = true
  661. set y = new regexp
  662. y.ignorecase = true
  663. set z = new regexp
  664. z.ignorecase = true
  665. xval  = "([0-9a-f]{1,4})" '1
  666. xregs = "(ax|bx|cx|dx|sp|bp|si|di|ds|es|ss|cs|ip)" '1
  667. xvlrg = "(?:" & xval & "|" & xregs & ")" '2
  668. xaddr = "(?:" & xvlrg & ":)?" & xvlrg '4=2+2
  669. xrng  = xaddr & "(?:\s*l\s*" & xvlrg & "|\s*" & xvlrg & ")" '8=4+2+2
  670. do while true
  671.   write "-"
  672.   t = timer
  673.   cl = trim(readln)
  674.   u = timer 'use input speed to determine input redirection
  675.  if (u - t) < 0.03 then writeln "" 'fast = input redirected
  676.  on error goto 0
  677.   select case ucase(left(cl, 1))
  678.     case "C"  compare
  679.     case "D"  dump
  680.     case "E"  enter
  681.     case "F"  fill
  682.     case "H"  hexCalc
  683.     case "L"  load
  684.     case "M"  move
  685.     case "N"  name
  686.     case "Q"  wscript.quit
  687.     case "R"  register
  688.     case "S"  search
  689.     case "W"  writefile
  690.     case "?"  help
  691.     case else if cl <> "" then writeln "Error"
  692.   end select
  693. loop
Add Comment
Please, Sign In to add comment