#!/usr/bin/wish

# ---------------------------------------
# Some globals
proc readPipeDiscard { f } {
   set str 0
   while { $str <= 0 } {
      set str [gets $f]
   }
   puts "discard $str"
   return
}
proc readPipeToVar { f in_var} {
   global VarSet $in_var

   if { [eof $f] } { puts "end of file\n" }
   set rv [gets $f]
   if { $VarSet == 0 } {
      set $in_var  "$rv"
      set VarSet 1
   }
   return
}
proc readPipeToList { f in_list } {
   global CmdStatus
	if { [eof $f] } { puts "eof reading pipe!\n" }
	set rv [gets $f]
	if { $rv == ";;" } {
	   set CmdStatus 1
	} else {
	   set $in_list [linsert $$in_list end "$rv"]
	}
	return
}

proc readPipeToWindow { f win } {
   global CmdStatus
   set str [gets $f]

   if { $str ==";;" } {
      set CmdStatus 1
   } else {
      switch -- $win {
         display    { printDisplay $str }
         console    { printConsole $str }
			names      { printNames $str }
			functions  { printExports $str }
			imports    { printImports $str }
			exports    { printNames $str }
			strings    { printStrings $str }
         discard    { }
      }
   }
}

set t_name   "a.out"
set t_format "ELF"
set t_arch   "i386"
set t_lang    "C"
set t_asm    "intel"
set t_dis    "full"
set t_loadstat 0

set VarSet 0
set CmdStatus 0
set CmdOutputType display


# Open the bastard
set rv [auto_execok bastard]
if { $rv > 0 && $rv != "" } { 
   set bastard_prog "bastard" 
} else {
   set bastard_prog "./bastard"
}
set bastard_opts "-q" 
set bastard_home  ""
set bPipe [ open "|$bastard_prog $bastard_opts" r+]
fconfigure $bPipe -blocking 1 -buffering line
puts $bPipe {printf(GetBastardHome());printf("\n");}
flush $bPipe
gets $bPipe
set bastard_home [gets $bPipe]
fconfigure $bPipe -blocking 0 -buffering line
fileevent $bPipe readable [list readPipeDiscard $bPipe]

#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# GUI crap
frame .mbar -borderwidth 1 -relief raised
pack .mbar -fill x

# ----------------- File Menu 
menubutton .mbar.file -text "File" -menu .mbar.file.m
pack .mbar.file -side left
menu .mbar.file.m
.mbar.file.m add command -label "Load Target" -command loadTarget
.mbar.file.m add command -label "Load BDB" -command loadBDB
.mbar.file.m add command -label "Save ASM" -command saveASM
.mbar.file.m add command -label "Save BDB" -command saveBDB
.mbar.file.m add command -label "Save LST" -command saveLST
.mbar.file.m add command -label "Exit" -command appExit

# ----------------- Navigate Menu
# ----------------- Disassembly Menu
menubutton .mbar.disasm -text "Disassembly" -menu .mbar.disasm.m -state disabled
pack .mbar.disasm -side left
menu .mbar.disasm.m
.mbar.disasm.m add command -label "Show Header" -command showHeader
.mbar.disasm.m add command -label "Show Assembly" -command showListing
# ----------------- DB Menu
# ----------------- Windows Menu
menubutton .mbar.windows -text "Windows" -menu .mbar.windows.m 
pack .mbar.windows -side left
menu .mbar.windows.m
.mbar.windows.m add command -label "Console" -command {
      if { [winfo ismapped .console] == 1 } { wm withdraw .console 
      } else { wm deiconify .console }  }
.mbar.windows.m add command -label "_____________"
.mbar.windows.m add command -label "Exports" -command {doShowExports}
.mbar.windows.m add command -label "Functions" -command {doShowFunctions}
.mbar.windows.m add command -label "Imports" -command {doShowImports}
.mbar.windows.m add command -label "Names" -command { doShowNames }
.mbar.windows.m add command -label "Strings" -command {doShowStrings }
.mbar.windows.m add command -label "_____________"
.mbar.windows.m add command -label "Clear Display" -command  {
   .display.t configure -state normal
   .display.t delete 1.0 end 
   .display.t configure -state  disabled }
.mbar.windows.m add command -label "Clear Console" -command {
   .console.out configure -state normal
   .console.out delete 1.0 end 
   .console.out configure -state  disabled }
# ----------------- Help Menu
menubutton .mbar.help -text "Help" -menu .mbar.help.m 
pack .mbar.help -side right
menu .mbar.help.m
.mbar.help.m add command -label "About" -command {
   tk_messageBox -icon info -title about -type ok \
   -message "\tLittle Grey Bastard \nTk front end to the bastard\n\t2001 _m"}
.mbar.help.m add command -label "Manual" -command {showFile bastard.txt}
.mbar.help.m add command -label "DB Layout" -command {showFile DBSchema.txt}
.mbar.help.m add command -label "BC Scripts" -command {showFile BCScript.txt}
.mbar.help.m add command -label "______________"
.mbar.help.m add command -label "Disasm HowTo" -command {showFile Disasm-HOWTO.txt}
.mbar.help.m add command -label "Function HowTo" -command {showFile Function-HOWTO.txt }
.mbar.help.m add command -label "Struct HowTo" -command {showFile Structure-HOWTO.txt }

# ----------------- Main Text Widget
frame .display
text .display.t -bd 3 -relief sunken -width 80 -height 40 -yscrollcommand {.display.ysb set} -xscrollcommand {.display.xsb set} -wrap none -state disabled
scrollbar .display.ysb -orient vertical -command {.display.t yview}
scrollbar .display.xsb -orient horizontal -command {.display.t xview}
pack .display.ysb -side right -fill y
pack .display.xsb -side bottom  -fill x
pack .display.t -side left -fill both -expand 1
pack .display -expand yes -fill both

# =========================================================================
# ----------------- target open dialog
toplevel .dlgTgt
frame .dlgTgt.tName -relief sunken -bd 2
label .dlgTgt.tName.label -text "Target:"
entry .dlgTgt.tName.t 
button .dlgTgt.tName.b -text Browse -command {.dlgTgt.tName.t insert end [tk_getOpenFile]}
pack .dlgTgt.tName.label -side left 
pack .dlgTgt.tName.t -side left
pack .dlgTgt.tName.b -side right

frame .dlgTgt.a
frame .dlgTgt.a.tFormat
label .dlgTgt.a.tFormat.label -text "File Format:"
listbox .dlgTgt.a.tFormat.lbox -width 15 -height 3 -yscrollcommand {.dlgTgt.a.tFormat.sbar set }
scrollbar .dlgTgt.a.tFormat.sbar -command {.dlgTgt.a.tFormat.lbox yview}
pack .dlgTgt.a.tFormat.label -side top
pack .dlgTgt.a.tFormat.lbox -side left
pack .dlgTgt.a.tFormat.sbar -side right
pack .dlgTgt.a.tFormat -side left
foreach i  [ glob -nocomplain $bastard_home/formats/*.bc ]  {
   .dlgTgt.a.tFormat.lbox insert end [string range $i 10 [expr [string length $i] - 4]]
}
foreach i [ glob -nocomplain $bastard_home/formats/lib*.so ] { 
   .dlgTgt.a.tFormat.lbox insert end [string range $i 13 [expr [string length $i] - 4]]
}
.dlgTgt.a.tFormat.lbox selection set 0

frame .dlgTgt.a.tArch
label .dlgTgt.a.tArch.label -text "CPU Architecture:"
listbox .dlgTgt.a.tArch.lbox -width 15 -height 3 -yscrollcommand {.dlgTgt.a.tArch.sbar set }
scrollbar .dlgTgt.a.tArch.sbar -command {.dlgTgt.a.tArch.lbox yview}
pack .dlgTgt.a.tArch.label -side top
pack .dlgTgt.a.tArch.lbox -side left
pack .dlgTgt.a.tArch.sbar -side right
pack .dlgTgt.a.tArch -side right
#set bastard_home "."
foreach i  [ glob -nocomplain $bastard_home/arch/*.bc ]  {
   .dlgTgt.a.tArch.lbox insert end [string range $i 7 [expr [string length $i] - 4]]
}
foreach i  [ glob -nocomplain $bastard_home/arch/lib*.so ]  {
   .dlgTgt.a.tArch.lbox insert end [string range $i 10 [expr [string length $i] - 4]]
}
.dlgTgt.a.tArch.lbox selection set 0

frame .dlgTgt.b
frame .dlgTgt.b.tAsm
label .dlgTgt.b.tAsm.label -text "Output Assembler:"
listbox .dlgTgt.b.tAsm.lbox -width 15 -height 3 -yscrollcommand {.dlgTgt.b.tAsm.sbar set }
scrollbar .dlgTgt.b.tAsm.sbar -command {.dlgTgt.b.tAsm.lbox yview}
pack .dlgTgt.b.tAsm.label -side top
pack .dlgTgt.b.tAsm.lbox -side left
pack .dlgTgt.b.tAsm.sbar -side right
pack .dlgTgt.b.tAsm -side left
foreach i  [ glob -nocomplain $bastard_home/asm/*.bc ]  {
   .dlgTgt.b.tAsm.lbox insert end [string range $i 6 [expr [string length $i] - 4]]
}
foreach i  [ glob -nocomplain $bastard_home/asm/lib*.so ]  {
   .dlgTgt.b.tAsm.lbox insert end [string range $i 9 [expr [string length $i] - 4]]
}
.dlgTgt.b.tAsm.lbox selection set 0

frame .dlgTgt.b.tLang
label .dlgTgt.b.tLang.label -text "High-Level Language:"
listbox .dlgTgt.b.tLang.lbox -width 15 -height 3 -yscrollcommand {.dlgTgt.b.tLang.sbar set }
scrollbar .dlgTgt.b.tLang.sbar -command {.dlgTgt.b.tLang.lbox yview}
pack .dlgTgt.b.tLang.label -side top
pack .dlgTgt.b.tLang.lbox -side left
pack .dlgTgt.b.tLang.sbar -side right
pack .dlgTgt.b.tLang -side right 
foreach i  [ glob -nocomplain $bastard_home/lang/*.bc ]  {
   .dlgTgt.b.tLang.lbox insert end [string range $i 7 [expr [string length $i] - 4]]
}
foreach i  [ glob -nocomplain $bastard_home/lang/lib*.so ]  {
   .dlgTgt.b.tLang.lbox insert end [string range $i 10 [expr [string length $i] - 4]]
}
.dlgTgt.b.tLang.lbox selection set 0

frame .dlgTgt.bot -relief sunken -bd 2
button .dlgTgt.bot.ok -text OK -command { set t_loadstat 1 }
button .dlgTgt.bot.cancel -text cancel -command {wm withdraw .dlgTgt}
pack .dlgTgt.bot.ok -side left
pack .dlgTgt.bot.cancel -side right

pack .dlgTgt.tName -side top -fill x
pack .dlgTgt.a -side top
pack .dlgTgt.b -side top
pack .dlgTgt.bot -side bottom -fill x

wm withdraw .dlgTgt
# =========================================================================
# more friggin windows
#    Console
toplevel .console
text .console.out -bd 3 -relief sunken -width 80 -height 10 -yscrollcommand {.console.ysb set} -xscrollcommand {.console.xsb set} -wrap none -state disabled
scrollbar .console.ysb -orient vertical -command {.console.out yview}
scrollbar .console.xsb -orient horizontal -command {.console.out xview}
entry .console.in -bd 3 -relief sunken -width 80 
pack .console.in -side bottom -fill x -expand 1
pack .console.ysb -side right -fill y
pack .console.out -side top -fill x -expand 1
pack .console.xsb -side top  -fill x
wm withdraw .console

event add <<CMD_Enter>> <Key-Return>
bind .console.in <<CMD_Enter>> { 
     set cmd [.console.in get]
	  sendBastardCmd  $cmd win console 
	  .console.in delete 0 end
	  }


# Names 

# Functions

# Sections

# Imports 

# Exports

#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# Back to Normal Execution :) 




proc printConsole { str } {
   .console.out configure -state normal
   .console.out insert end "$str\n"
	.console.out see end
   .console.out configure -state disabled 
}

proc printDisplay { str } {
   .display.t configure -state normal
   .display.t insert end "$str\n"
	.display.t see end 
   .display.t configure -state disabled 
}

proc printNames { str } {
   .names.t configure -state normal
   .names.t insert end "$str\n" 
   .names.t configure -state disabled 
}
proc printImports { str } {
   .imports.t configure -state normal
   .imports.t insert end "$str\n" 
   .imports.t configure -state disabled 
}
proc printExports { str } {
   .exports.t configure -state normal
   .exports.t insert end "$str\n" 
   .exports.t configure -state disabled 
}
proc printStrings { str } {
   .strings.t configure -state normal
   .strings.t insert end "$str\n" 
   .strings.t configure -state disabled 
}
proc printFunctions { str } {
   .functions.t configure -state normal
   .functions.t insert end "$str\n" 
   .functions.t configure -state disabled 
}

proc sendBastardCmd { cmd outtype param} {
   global CmdStatus bPipe
   
   set CmdStatus 0

   fileevent $bPipe readable {} 
   fconfigure $bPipe -blocking 1 -buffering line
   puts $bPipe $cmd
   gets $bPipe
	switch -- $outtype {
		win { fileevent $bPipe readable [list readPipeToWindow $bPipe $param]}
		lst { fileevent $bPipe readable [list readPipeToList $bPipe $param]}
		var { fileevent $bPipe readable [list readPipeToVar $bPipe $param]}
	}
   fconfigure $bPipe -blocking 0 -buffering line
   # send Done command ';'
   puts $bPipe ";;"
   tkwait variable CmdStatus
   set CmdStatus 0
   fileevent $bPipe readable {} 
   #fileevent $bPipe readable [list readPipeDiscard $bPipe]
}

proc appExit {} {
   global bPipe
   puts $bPipe "q\n"
   flush $bPipe
   close $bPipe
   exit
}
proc loadTarget { } {
   global bPipe
   global t_name t_arch t_format t_lang t_asm t_dis
   global t_loadstat

   wm deiconify .dlgTgt
   grab set .dlgTgt
   tkwait variable t_loadstat
   grab release .dlgTgt
   wm withdraw .dlgTgt
   set t_name   [.dlgTgt.tName.t get]
   set t_arch   [.dlgTgt.a.tArch.lbox get active]
   set t_format [.dlgTgt.a.tFormat.lbox get active]
   set t_asm    [.dlgTgt.b.tAsm.lbox get active]
   set t_lang   [.dlgTgt.b.tLang.lbox get active]
   sendBastardCmd "LoadTarget( \"$t_name\" );" win console
   sendBastardCmd "SetTargetArch( \"$t_arch\" );" win console
   sendBastardCmd "SetTargetAssembler( \"$t_asm\" );" win console
   sendBastardCmd "SetTargetLanguage( \"$t_lang\" );" win console
   sendBastardCmd "SetTargetFormat( \"$t_format\" );" win console
   # TODO : make this next part conditional : dumb or full
   sendBastardCmd "DisassembleTarget(\"$t_dis\", NULL);" win console
   
   .mbar.disasm configure -state normal
}
proc loadBDB { } {
   global t_name
   set t_name [tk_getOpenFile]
   if { $t_name != "" } {
      sendBastardCmd "LoadBDB( \"$t_name\" );" win console
      .mbar.disasm configure -state normal
   }
}
proc saveBDB { } {
   sendBastardCmd "SaveDB( );" win console
}
proc saveASM { } {
   global t_name
   set tmp_name "${t_name}.asm"
   sendBastardCmd "SaveAsASM( $tmp_name );" win console
}
proc saveLST { } {
   global t_name
   set tmp_name "${t_name}.lst"
   sendBastardCmd "SaveAsLST( $tmp_name );" win console
}
proc showHeader {} {
   global bPipe
   sendBastardCmd "H" win display
}
proc showListing {} {
   global bPipe
   sendBastardCmd "D" win display
}
proc showFile { doc } {
   global bastard_home
   set d [string range $doc 0 5]
   toplevel .help${d}
   text .help${d}.lb -width 80 -height 20 \
           -yscrollcommand ".help${d}.ysb set" \
           -xscrollcommand ".help${d}.xsb set" 
   scrollbar .help${d}.ysb -orient vertical -command ".help${d}.lb yview"
   scrollbar .help${d}.xsb -orient horizontal -command ".help${d}.lb xview"
   pack .help${d}.xsb -side bottom -fill x
   pack .help${d}.ysb -side right -fill y
   pack .help${d}.lb -side left 
   
   set fID [open "$bastard_home/doc/$doc" r]
      while { [gets $fID line]  >= 0 } {
         .help${d}.lb insert end "$line\n"
      }
      close $fID
   .help${d}.lb configure  -state disabled
}

proc doShowNames {}  {
   global bPipe CmdStatus
   set crap 0

	toplevel .names

   text .names.t -width 80 -height 20 -state disabled\
           -yscrollcommand ".names.ysb set" \
           -xscrollcommand ".names.xsb set" 
   scrollbar .names.ysb -orient vertical -command ".names.t yview"
   scrollbar .names.xsb -orient horizontal -command ".names.t xview"
   pack .names.xsb -side bottom -fill x
   pack .names.ysb -side right -fill y
   pack .names.t -side left 
	
		
	set n_list ""
   fileevent $bPipe readable {} 
   #fileevent $bPipe readable [list readPipeDiscard $bPipe]
   fconfigure $bPipe -blocking 1 -buffering line
   puts $bPipe  "{{"
   gets $bPipe
   puts $bPipe {struct name n;}
   printConsole [gets $bPipe]
   puts $bPipe {int rv;} 
   printConsole [gets $bPipe]
   puts $bPipe {rv = DBIndexFirst(NAME_RVA, &n);}
   printConsole [gets $bPipe]
   puts $bPipe "while (rv) {"
   printConsole [gets $bPipe]
   puts $bPipe {   printf("%s|%x|%x\n",n.name, n.rva, n.type);} 
   printConsole [gets $bPipe]
   puts $bPipe {   rv = DBIndexNext(NAME_RVA, &n);}
   printConsole [gets $bPipe]
   puts $bPipe "}" 
   printConsole [gets $bPipe]
	sendBastardCmd "}}" win names

}
proc doShowFunctions {} {
   global bPipe CmdStatus
   set crap 0
	toplevel .functions
   text .functions.t -width 80 -height 20 \
           -yscrollcommand ".functions.ysb set" \
           -xscrollcommand ".functions.xsb set" 
   scrollbar .functions.ysb -orient vertical -command ".functions.t yview"
   scrollbar .functions.xsb -orient horizontal -command ".functions.t xview"
   pack .functions.xsb -side bottom -fill x
   pack .functions.ysb -side right -fill y
   pack .functions.t -side left
   fileevent $bPipe readable {} 
   #fileevent $bPipe readable [list readPipeDiscard $bPipe]
   fconfigure $bPipe -blocking 1 -buffering line
   puts $bPipe  "{{"
   gets $bPipe
   puts $bPipe {struct function f;}
   printConsole [gets $bPipe]
   puts $bPipe {struct name *n;}
   printConsole [gets $bPipe]
   puts $bPipe {int rv;} 
   printConsole [gets $bPipe]
   puts $bPipe {rv = DBIndexFirst(FUNCTION_RVA, &f);}
   printConsole [gets $bPipe]
   puts $bPipe "while (rv) {"
   printConsole [gets $bPipe]
   puts $bPipe "   if (n = GetNameObject(f.rva)) {"
   printConsole [gets $bPipe]
   puts $bPipe {      printf("%s|%x\n",n->name, f.rva);} 
   printConsole [gets $bPipe]
   puts $bPipe {      free(n); }
   printConsole [gets $bPipe]
   puts $bPipe "   }" 
   printConsole [gets $bPipe]
   puts $bPipe {   rv = DBIndexNext(FUNCTION_RVA, &f);}
   printConsole [gets $bPipe]
   puts $bPipe "}" 
   printConsole [gets $bPipe]
   sendBastardCmd "}}" win functions
}
proc doShowImports {} {
   global bPipe CmdStatus
   set crap 0
	
	toplevel .imports
   text .imports.t -width 80 -height 20 \
           -yscrollcommand ".imports.ysb set" \
           -xscrollcommand ".imports.xsb set" 
   scrollbar .imports.ysb -orient vertical -command ".imports.t yview"
   scrollbar .imports.xsb -orient horizontal -command ".imports.t xview"
   pack .imports.xsb -side bottom -fill x
   pack .imports.ysb -side right -fill y
   pack .imports.t -side left
   fileevent $bPipe readable {} 
   #fileevent $bPipe readable [list readPipeDiscard $bPipe]
   fconfigure $bPipe -blocking 1 -buffering line
   puts $bPipe  "{{"
   gets $bPipe
   puts $bPipe {struct import_addr i;}
   printConsole [gets $bPipe]
   puts $bPipe {char iname[64], lname[64];}
   printConsole [gets $bPipe]
   puts $bPipe {int rv;} 
   printConsole [gets $bPipe]
   puts $bPipe {rv = DBIndexFirst(IMPORT_ADDR_RVA, &i);}
   printConsole [gets $bPipe]
   puts $bPipe "while (rv) {"
   printConsole [gets $bPipe]
   puts $bPipe {   GetImportName(i.rva, iname); } 
   printConsole [gets $bPipe]
   puts $bPipe {   GetImportLib(i.rva, lname); } 
   printConsole [gets $bPipe]
   puts $bPipe {   printf("%s|%s|%08x\n",lname, iname, i.rva);} 
   printConsole [gets $bPipe]
   puts $bPipe {   rv = DBIndexNext(IMPORT_ADDR_RVA, &i);}
   printConsole [gets $bPipe]
   puts $bPipe "}" 
   printConsole [gets $bPipe]
   sendBastardCmd "}}" win imports
}
proc doShowExports {} {
   global bPipe CmdStatus
   set crap 0
	
	toplevel .exports
   text .exports.t -width 80 -height 20 \
           -yscrollcommand ".exports.ysb set" \
           -xscrollcommand ".exports.xsb set" 
   scrollbar .exports.ysb -orient vertical -command ".exports.t yview"
   scrollbar .exports.xsb -orient horizontal -command ".exports.t xview"
   pack .exports.xsb -side bottom -fill x
   pack .exports.ysb -side right -fill y
   pack .exports.t -side left
   fileevent $bPipe readable {} 
   #fileevent $bPipe readable [list readPipeDiscard $bPipe]
   fconfigure $bPipe -blocking 1 -buffering line
   puts $bPipe  "{{"
   gets $bPipe
   puts $bPipe {struct export_addr e;}
   printConsole [gets $bPipe]
   puts $bPipe {struct name *n;}
   printConsole [gets $bPipe]
   puts $bPipe {int rv;} 
   printConsole [gets $bPipe]
   puts $bPipe {rv = DBIndexFirst(EXPORT_ADDR_RVA, &e);}
   printConsole [gets $bPipe]
   puts $bPipe "while (rv) {"
   printConsole [gets $bPipe]
   puts $bPipe "   if (n = GetNameObject(e.rva)) {" 
   printConsole [gets $bPipe]
   puts $bPipe {       printf("%08x|%s\n",e.rva, n->name);} 
   printConsole [gets $bPipe]
   puts $bPipe {       free(n);} 
   printConsole [gets $bPipe]
   puts $bPipe "   }" 
   printConsole [gets $bPipe]
   puts $bPipe {   rv = DBIndexNext(EXPORT_ADDR_RVA, &e);}
   printConsole [gets $bPipe]
   puts $bPipe "}" 
   printConsole [gets $bPipe]
   sendBastardCmd "}}" win exports
}
proc doShowStrings {} {
   global bPipe CmdStatus
   set crap 0   
   toplevel .strings
   text .strings.t -width 80 -height 20 \
           -yscrollcommand ".strings.ysb set" \
           -xscrollcommand ".strings.xsb set" 
   scrollbar .strings.ysb -orient vertical -command ".strings.t yview"
   scrollbar .strings.xsb -orient horizontal -command ".strings.t xview"
   pack .strings.xsb -side bottom -fill x
   pack .strings.ysb -side right -fill y
   pack .strings.t -side left 
   fileevent $bPipe readable {} 
   #fileevent $bPipe readable [list readPipeDiscard $bPipe]
   fconfigure $bPipe -blocking 1 -buffering line
   puts $bPipe  "{{"
   gets $bPipe
   puts $bPipe {struct string s;}
   printConsole [gets $bPipe]
   puts $bPipe {int rv;} 
   printConsole [gets $bPipe]
   puts $bPipe {rv = DBIndexFirst(STRING_RVA, &s);}
   printConsole [gets $bPipe]
   puts $bPipe "while (rv) {"
   printConsole [gets $bPipe]
   puts $bPipe {   printf("%s|%x\n",s.text, s.rva);} 
   printConsole [gets $bPipe]
   puts $bPipe {   rv = DBIndexNext(STRING_RVA, &s);}
   printConsole [gets $bPipe]
   puts $bPipe "}" 
   printConsole [gets $bPipe]
   sendBastardCmd "}}" win strings
}
