Best way to hide strings on an .exe

Just starting out? Need help? Post your questions and find answers here.
ricardo
Addict
Addict
Posts: 2438
Joined: Fri Apr 25, 2003 7:06 pm
Location: Argentina

Best way to hide strings on an .exe

Post by ricardo »

vowels$ = Chr('a'+abs) + Chr('e'+abs) + Chr('i'+abs) + Chr('o'+abs) + Chr('u'+abs) ?

I want to hide some strings, that cant be easily seeing for the user, whats the best way to do it?

Thanks in advance
ARGENTINA WORLD CHAMPION
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Best way to hide strings on an .exe

Post by IdeasVacuum »

Put the strings in a file, encrypted (or just use writedata()). At run time read the file, decrypt, assign to variables. I think that file can be included in the exe as a resource?
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
eJan
Enthusiast
Enthusiast
Posts: 366
Joined: Sun May 21, 2006 11:22 pm
Location: Sankt Veit am Flaum

Re: Best way to hide strings on an .exe

Post by eJan »

Why not try with: Base64Decoder(), Base64Encoder()
Image
User avatar
ar-s
Enthusiast
Enthusiast
Posts: 344
Joined: Sat Oct 06, 2007 11:20 pm
Location: France

Re: Best way to hide strings on an .exe

Post by ar-s »

The problem is that the string will not be hide in memory... A simple dump should be enougth to reveal it.
~Ar-S~
My Image Hoster for PB users
My webSite (french) with PB apps : LDVMULTIMEDIA
PB - 3.x / 5.7x / 6 - W11 x64 - Ryzen 7 3700x / #Rpi4

Code: Select all

r3p347 : 7ry : un71l d0n3 = 1
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Best way to hide strings on an .exe

Post by IdeasVacuum »

Well your average User is not going to be doing that!
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
KJ67
Enthusiast
Enthusiast
Posts: 218
Joined: Fri Jun 26, 2009 3:51 pm
Location: Westernmost tip of Norway

Re: Best way to hide strings on an .exe

Post by KJ67 »

This is what I used in a project which included larger data blocks, it will hide your text even if its purpose was a slightly other.

Code: Select all

;***********************************
;* Author   : Kent Jofur
;* Name     : Insert Packed-Text
;* Arguments: %TEMPFILE %CURSOR
;***********************************
EnableExplicit

;- Declares
Declare BestPackAndInsert(Text$, line, file$)
Declare ErrWin(msg$)

#MAXPERLINE   = 12

Define *ptr, line, Text$, Win, w, h, i
If CountProgramParameters()<>2
  ErrWin("Usage: %TEMPFILE %CURSOR")
Else
  win = OpenWindow(#PB_Any, #PB_Ignore, #PB_Ignore, 600, 400, "Enter Text", #PB_Window_SystemMenu)
  If Win=#NUL
    ErrWin("Failed to open window")
  EndIf
  w= WindowWidth(win)
  h= WindowHeight(win)
  EditorGadget(0, 0, 0, w, h-22)
  ButtonGadget(1, w/2-42, h-20, 42<<1, 18, "Process")
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        End
      Case #PB_Event_Gadget
        If EventGadget()=1 And EventType()=#PB_EventType_LeftClick
          Break
        EndIf
    EndSelect
  ForEver
  BestPackAndInsert(GetGadgetText(0), Val(StringField(ProgramParameter(1), 1, "x")), ProgramParameter(0))
  CloseWindow(win)
EndIf

Procedure BestPackAndInsert(Text$, line, file$)
  Protected *p1, *p2, l, i, j=-1, bestP=#MAXLONG, p, *p
  Protected fh, filetype, dtype, LineStarted, datasize, s.s
  l = Len(Text$)
  *p1 = @Text$
  *p2 = AllocateMemory(l*SizeOf(Character) + 2*SizeOf(Integer))
  If *p1=#NUL Or *p2= #NUL
    ErrWin("Failed to allocate memory")
  EndIf
  For i=0 To 9
    p=PackMemory(*p1, *p2, l*SizeOf(Character), i)
    If p=0: Continue: EndIf
    If p < bestP
      bestP = p
      j = i
    EndIf
  Next i
  If bestP=#MAXLONG: ProcedureReturn : EndIf
  p=PackMemory(*p1, *p2, l*SizeOf(Character), j)
  *p=ReAllocateMemory(*p2, p)
  ;-------------------------------------------------------
  datasize = MemorySize(*p)
  If datasize=0: ProcedureReturn: EndIf
  NewList Line$()
  fh = ReadFile(#PB_Any, file$)
  If fh
    filetype = ReadStringFormat(fh)
    While Eof(fh)=#False
      AddElement(Line$())
      Line$()=ReadString(fh)
    Wend
    CloseFile(fh)
  EndIf
  fh = CreateFile(#PB_Any, file$)
  If fh
    FileBuffersSize(fh, 12*1024)
    i=0
    ForEach Line$()
      i+1
      WriteStringN(fh, Line$())
      If i=line
        s="PackedText_"+FormatDate("%yyyy_%mm_%dd_%hh_%ii_%ss", Date())+"_p"+Str(j)
        WriteStringN(fh, "DataSection"+#CRLF$+"Size"+s+":")
        WriteStringN(fh, "Data.i "+Str(l*SizeOf(Character))+"; packed to "+Str(p)+" bytes.")
        WriteStringN(fh, "Start"+s+": ;PackLevel=" + Str(j)+ ", Packed to=" + StrD(100.0*p/(1.0+l*SizeOf(Character)),2)+"%")
        While datasize > 0
          If datasize >= SizeOf(Quad)
            If LineStarted=#False
              dtype=SizeOf(Quad)
              LineStarted + 1
              WriteString(fh, "Data.q $"+RSet(Hex(PeekQ(*p)), SizeOf(Quad)*2,"0"))
              *p+SizeOf(Quad): datasize-SizeOf(Quad)
            Else
              LineStarted + 1
              WriteString(fh, ", $"+RSet(Hex(PeekQ(*p)), SizeOf(Quad)*2,"0"))
              *p+SizeOf(Quad): datasize-SizeOf(Quad)
            EndIf
            If LineStarted >= #MAXPERLINE
              WriteStringN(fh, "")
              LineStarted=#False
            EndIf
          Else ; < Quad
            If dtype=SizeOf(Quad)
              WriteStringN(fh, "")
              LineStarted=#False
            EndIf
            If LineStarted=#False
              dtype=SizeOf(Ascii)
              LineStarted=#True
              WriteString(fh, "Data.a $"+RSet(Hex(PeekA(*p)), SizeOf(Ascii)*2,"0"))
              *p+SizeOf(Ascii): datasize-SizeOf(Ascii)
            Else
              WriteString(fh, ", $"+RSet(Hex(PeekA(*p)), SizeOf(Ascii)*2,"0"))
              *p+SizeOf(Ascii): datasize-SizeOf(Ascii)
            EndIf
            If LineStarted >= #MAXPERLINE
              WriteStringN(fh, "")
              LineStarted=#False
            EndIf
          EndIf
        Wend
        WriteStringN(fh, #CRLF$+"End"+s+":"+#CRLF$+"EndDataSection")
      EndIf
    Next
    CloseFile(fh)
  EndIf
EndProcedure

Procedure ErrWin(msg$)
  Protected win, timer
  win = OpenWindow(#PB_Any, #PB_Ignore, #PB_Ignore, 200, 25, "Error", #PB_Window_SystemMenu)
  If win
    If LoadFont(0, "Segoe UI", 9)
      SetGadgetFont(#PB_Default, FontID(0))
    EndIf
    AddWindowTimer(win, 0, 20*1000)
    TextGadget(0, 2, 2, WindowWidth(win)-4, WindowHeight(win)-4, msg$, #PB_Text_Border )
    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_Timer, #PB_Event_CloseWindow
          Break
      EndSelect
    ForEver
    CloseWindow(win)
  EndIf
  End
EndProcedure
Install it like,
Image

Than just retrieve your text with something like;

Code: Select all

*mem = AllocateMemory(?SizePackedText_2012_08_28_19_14_27_p0)
len  = UnpackMemory(?StartPackedText_2012_08_28_19_14_27_p0, *mem)
If OpenConsole()
  Print(PeekS(*mem))
  Input()
EndIf

DataSection
  SizePackedText_2012_08_28_19_14_27_p0:
  Data.i 100; packed to 70 bytes.
  StartPackedText_2012_08_28_19_14_27_p0: ;PackLevel=0, Packed to=69.31%
  Data.q $073800000064434A, $D24720006A1106CD, $23E8CC8D0303E823, $0C6C47940C405C20, $AB8848D911B362B0, $3DC1C6918A23608D, $479863400A20981A, $AE22066CD86921DE
  Data.a $40, $E0, $00, $00, $00, $00
  EndPackedText_2012_08_28_19_14_27_p0:
EndDataSection
The best preparation for tomorrow is doing your best today.
User avatar
Kukulkan
Addict
Addict
Posts: 1396
Joined: Mon Jun 06, 2005 2:35 pm
Location: germany
Contact:

Re: Best way to hide strings on an .exe

Post by Kukulkan »

Simply use some xor way.

[edit]See next post...[/edit]

Kukulkan
Last edited by Kukulkan on Wed Aug 29, 2012 12:54 pm, edited 1 time in total.
User avatar
Kukulkan
Addict
Addict
Posts: 1396
Joined: Mon Jun 06, 2005 2:35 pm
Location: germany
Contact:

Re: Best way to hide strings on an .exe

Post by Kukulkan »

It was to easy. Here is the PB version:

Code: Select all

EnableExplicit

Procedure.s XCrypt(Phrase.s, Password.s)
  Protected NewPhrase.s = ""
  Protected Buffer.s = ""
  Protected Char.i = 0
  Protected x.i = 0, PPos.i = 0
  
  For x.i = 1 To Len(Phrase.s)
    PPos.i = PPos.i + 1
    If PPos.i > Len(Password.s): PPos.i = 1: EndIf
    Char.i = Asc(Mid(Phrase.s, x.i, 1)) ! Asc(Mid(Password.s, PPos.i, 1))
    Buffer.s = Buffer.s + Chr(Char.i)
    If Len(Buffer.s) > 1500
      NewPhrase.s = NewPhrase.s + Buffer.s
      Buffer.s =  ""
    EndIf
  Next
  NewPhrase.s = NewPhrase.s + Buffer.s
  Buffer.s =  ""
  ProcedureReturn NewPhrase.s
EndProcedure

Define Password.s = "pydLypwovIEthisfichsanVej3osht"
Define Secret.s = "The quick brown fox jumped over the lazy dog."

Define Encrypted.s = XCrypt(Secret.s, Password.s)

Debug "Encrypted: " + Encrypted.s

Define Decrypted.s = XCrypt(Encrypted.s, Password.s)

Debug "Decrypted: " + Decrypted.s
Kukulkan
MachineCode
Addict
Addict
Posts: 1482
Joined: Tue Feb 22, 2011 1:16 pm

Re: Best way to hide strings on an .exe

Post by MachineCode »

ricardo wrote:vowels$ = Chr('a'+abs) + Chr('e'+abs) + Chr('i'+abs) + Chr('o'+abs) + Chr('u'+abs)
Since you posted it: the above works fine here. What's the problem?
Microsoft Visual Basic only lasted 7 short years: 1991 to 1998.
PureBasic: Born in 1998 and still going strong to this very day!
User avatar
em_uk
Enthusiast
Enthusiast
Posts: 366
Joined: Sun Aug 08, 2010 3:32 pm
Location: Manchester UK

Re: Best way to hide strings on an .exe

Post by em_uk »

My bad code that I use. Obviously if you were really determine you could crack this, but for average stuff it works quite well. When the program is ready for release, I remove the encoding from the PassToHex procedure.

Code: Select all

; PassToHex by em_uk (Self Encryption from Droopy lib)

ProcedureDLL.s SelfEncryptionA(text.s,en.l) ; Encrypt a String (text) if en=#True / Decrypt if en=#False
  k1=Len(text) 
  If k1>0 
    *p=@text 
    k2=PeekB(*p) & $FF 
    r=k1 ! k2 
    If r<>0 : PokeB(*p,r) : EndIf 
    For i=2 To Len(text) 
      *p+1 
      If en : k1=PeekB(*p-1) & $FF : Else : k1=k2 : EndIf 
      k2=PeekB(*p) 
      r=k1 ! k2 
      If r<>0 : PokeB(*p,r) : EndIf 
    Next 
  EndIf 
  ProcedureReturn text 
EndProcedure 

Procedure.s PassToHex(passworda$="data",enc=#True)
  If enc
    tbufa$=SelfEncryptionA(passworda$,#True)
    passworda$=tbufa$
    tlen=Len(passworda$) : loc = 0
    tbuf$="" : loc = 0 
    For n = 0 To tlen-1
      loc=@passworda$+n
      result$= RSet(Hex(PeekB(loc)),2,"0")
      tbuf$+result$      
    Next       
    SetClipboardText("key$="+#DQUOTE$+tbuf$+#DQUOTE$)
    ProcedureReturn tbuf$      
  Else
    tlen=Len(passworda$)
    tbuf$=""
    For n= 0 To tlen
      n=n+1
      loc=@passworda$+n
      bufa$=Mid(passworda$,n,2)
      result$=Chr(Val("$"+bufa$))
      tbuf$+result$    
    Next
    tbufa$=SelfEncryptionA(tbuf$,#False)    
    ProcedureReturn tbufa$    
  EndIf  
EndProcedure

key$="ALL THE GIRLS LOVE ME"
Debug PassToHex(key$,#True) ; encrypts the string

; the procedure pastes the result to the clipboard.
; End

key$="5418547420682D0D4A03511D4E6E226D3B7E5E1356"
MessageRequester("Oh hai",PassToHex(key$,#False)) ; decrypts the string

----

R Tape loading error, 0:1
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4946
Joined: Sun Apr 12, 2009 6:27 am

Re: Best way to hide strings on an .exe

Post by RASHAD »

You can play with the next snippet

Code: Select all

Debug PeekS(?sec_1)
Debug PeekS(?sec_3)


DataSection
sec_1:
Data.s "a"

sec_2:
Data.s "o"

sec_3:
Data.s "e"

sec_4:
Data.s "u"

sec_5:
Data.s "i"

EndDataSection

Egypt my love
User avatar
Shield
Addict
Addict
Posts: 1021
Joined: Fri Jan 21, 2011 8:25 am
Location: 'stralia!
Contact:

Re: Best way to hide strings on an .exe

Post by Shield »

Yeah except the strings are visible in plain text. :wink:
Just encrypt them like explained above.
Image
Blog: Why Does It Suck? (http://whydoesitsuck.com/)
"You can disagree with me as much as you want, but during this talk, by definition, anybody who disagrees is stupid and ugly."
- Linus Torvalds
User avatar
Tenaja
Addict
Addict
Posts: 1959
Joined: Tue Nov 09, 2010 10:15 pm

Re: Best way to hide strings on an .exe

Post by Tenaja »

Several valid methods have been posted already. Here is one that is slightly stronger than your original code, because instead of a single constant offset, it uses a slight variation--and of course, you can change that, by editing #SafetyOffset. The #LinePrefix can be edited as needed; I just set it up for quick pasting of data strings. Note that #SafetyOffset does two things: First, it makes all of the characters visible (i.e. >31), and second, it ensures there are no double-quotes in the string, which can mess up your pasted data. The bad thing about it is that it makes capital characters print just a few characters higher--but still obfuscated.

This is best suited for "minimal" strings, and it is not strong encryption--you can adapt the editor to include that if you wish, but I think that has already been posted as a plug-in. It is just a simple hider. It can also be easily converted to handle text files if you need "many" strings, but I leave that to you. (Please post code if you do it.)

I apologize in advance that it is not a great example of variable naming, but the code is so simple it should not be difficult to read.

Code: Select all

#LinePrefix = "Data.s "
#LinePrefix1 = #TAB$ + #LinePrefix + #DQUOTE$
#LinePrefix2 = #TAB$ + #LinePrefix + #DQUOTE$

#LineSuffix1 = #DQUOTE$ + #CR$
#LineSuffix2 = #DQUOTE$

#SafetyOffset1 = 35
#SafetyOffset2 = 37

Global.s	dbs1, dbs2





; Place only this proc in your executable code.
; Call it with the two data strings, and it returns the useable string.

Procedure.s RecoverString(s1.s, s2.s)	; short demo adds ascii values of strings.
	Protected.i x = 1
	Protected.s s
	
	While Mid(s1, x, 1)
		v1 = Asc(Mid(s1,x,1))
		v2 = Asc(Mid(s2,x,1))
		s + Chr(v1 + v2 - #SafetyOffset1 - #SafetyOffset2)			; Add the "no invisible character" offset.
		
		x+1
	Wend
	
	ProcedureReturn s
	
EndProcedure



; The following code is just for generating the obfuscated text.

Procedure.s ObfuscateString(s.s)
	Protected.i x = 1, v1, v2
	Protected.s s1, s2
	
	s1 = s2
	
	While Mid(s, x, 1) 
		v1 = Asc(Mid(s,x,1))
		v2 = v1/2
		v2 + Random(8)		; add a little randomness
		v1 - v2
		V1 + #SafetyOffset1	; Ensure only visible characters, and no double quotes
		V2 + #SafetyOffset2
		
		s1 + Chr(v1)
		s2 + Chr(v2)
		x+1
	Wend
	
	dbs1 = s1
	dbs2 = s2
	
	s1 = #LinePrefix1 + s1 + #LineSuffix1
	s2 = #LinePrefix2 + s2 + #LineSuffix2
	ProcedureReturn s1 + s2 + "		; " + #DQUOTE$ + s + #DQUOTE$
	
EndProcedure



; Shows possible flags of StringGadget in action...
If OpenWindow(0, 0, 0, 322, 205, "StringGadget Flags", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
	StringGadget(0, 8,  10, 306, 20, "Normal StringGadget...")
	EditorGadget(1, 8,  35, 306, 150)
	
	Repeat : 
		Event = WaitWindowEvent()
		
		Select Event
					
			Case #PB_Event_Gadget
					Select EventGadget()
						Case 0
								OutputText.s = ObfuscateString(GetGadgetText(0))
								SetGadgetText(1, OutputText)
								Debug RecoverString(dbs1, dbs2)		; demo to see recovered string
					EndSelect
		EndSelect
	Until Event = #PB_Event_CloseWindow
EndIf

edit: Added individual #LinePrefix's, and also a comment including original text. Also added a slightly random component; duplicate strings do not generate identical pairs.


Sample output:

Code: Select all

	Data.s "TNQPOMLNRPSNPQTMOP"
	Data.s "U[XYZ\][WYV[YXU\ZY"		; "aaaaaaaaaaaaaaaaaa"
Last edited by Tenaja on Wed Aug 29, 2012 5:13 pm, edited 3 times in total.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4946
Joined: Sun Apr 12, 2009 6:27 am

Re: Best way to hide strings on an .exe

Post by RASHAD »

Hi Shield

Still shown in plain text ?
I doubt
I said he can play with the method

Code: Select all

Debug Chr(PeekB(?sec_1+8)+PeekB(?sec_1+4)*100)
Debug Chr(PeekB(?sec_1+16)+PeekB(?sec_1+12)*100)

DataSection
sec_1:
Data.i 97,01,11,01,01,01,17,01,05
EndDataSection

Egypt my love
User avatar
Shield
Addict
Addict
Posts: 1021
Joined: Fri Jan 21, 2011 8:25 am
Location: 'stralia!
Contact:

Re: Best way to hide strings on an .exe

Post by Shield »

:wink:
Image
Blog: Why Does It Suck? (http://whydoesitsuck.com/)
"You can disagree with me as much as you want, but during this talk, by definition, anybody who disagrees is stupid and ugly."
- Linus Torvalds
Post Reply