Demo Map Hidden Script

saw792

Is known to say things. That is all.
Reaction score
280
Hidden Script

I just thought I'd share this snippet I discovered. The demo map below shows how it is possible to hide code within other files in the map. In the example within the map, an admin password has been hidden within the model file imported in the map and retrieved through the use of gamecache.

You can see in the map script that at no stage is the comparison string set, yet when the correct password is typed the matching message appears.

Map Code:
JASS:
scope AdminPassword initializer Init
  
  globals
    private gamecache g = InitGameCache("preload.w3v")
  endglobals
  
  private function Conditions takes nothing returns boolean
    local string s = GetStoredString(g, "password", GetPlayerName(GetTriggerPlayer()))
    if GetEventPlayerChatString() == s and s != null then
      call DisplayTextToPlayer(GetTriggerPlayer(), 0, 0, "|cff00ff00Welcome, admin|r")
    else
      call DisplayTextToPlayer(GetTriggerPlayer(), 0, 0, "|cffff0000Incorrect admin code|r")
    endif
    return false
  endfunction
  
  private function Init takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterPlayerChatEvent(t, Player(0), "-", false)
    call TriggerAddCondition(t, Condition(function Conditions))
    call Preloader("war3mapimported\\model.mdx")
  endfunction
  
endscope
As I said above, this is the only code contained within the map script. It should always return the Incorrect Code message then, should it not? But it doesn't... Set your in game name to WorldEdit and type the correct code "-password1" to see the correct message.

Code inside 'model' file:
JASS:
globals
    gamecache g = InitGameCache("preload.w3v")
endglobals

function main takes nothing returns nothing
  call StoreString(g, "password", "WorldEdit", "-password1")
  call StoreString(g, "password", "saw792", "-24947341")
endfunction

function PreloadFiles takes nothing returns nothing
  call main()
endfunction
Further explanation:
The model file within the map is not actually a model file at all, it is just disguised as such. Inside is a simple JASS script. The Preloader() native called from the map script points to this file and automatically executes the PreloadFiles() function within the file. This then saves the password to the gamecache where it can be reloaded within the map script.

Limitations of this method:
Things that can't be used within the hidden script:
BJs
Timers
Triggers
TriggerExecute/Evaluate
TriggerSleepAction
I2S (and R2S I assume)
StringHash (GetHandleId?)
<probably lots more, this is all I have tested>

Things that can be used:
Function calls
Gamecache
Global variables
ExecuteFunc (calls function from the MAIN MAP SCRIPT ONLY, not the hidden script)
CreateUnit
UnitAddAbility
Issuing orders
<probably lots more, this is all I have tested>

Perhaps somebody can find a use for this beyond hiding variable setting and such. As it stands, getting the admin code from my example doesn't actually require you to open the file since you can just modify the map to display the stored string, but I believe that is beside the point right now.

Some Examples of Use:
Inside Map:
JASS:
scope Display initializer Init
  
  globals
    private string Code = &quot;-&quot;
  endglobals
  
  //! textmacro Code takes NUMBER, INTEGER
  function $NUMBER$ takes nothing returns nothing
    set Code = Code + I2S($INTEGER$)
  endfunction
  //! endtextmacro
  
  //! runtextmacro Code(&quot;Zero&quot;, &quot;0&quot;)
  //! runtextmacro Code(&quot;One&quot;, &quot;1&quot;)
  //! runtextmacro Code(&quot;Two&quot;, &quot;2&quot;)
  //! runtextmacro Code(&quot;Three&quot;, &quot;3&quot;)
  //! runtextmacro Code(&quot;Four&quot;, &quot;4&quot;)
  //! runtextmacro Code(&quot;Five&quot;, &quot;5&quot;)
  //! runtextmacro Code(&quot;Six&quot;, &quot;6&quot;)
  //! runtextmacro Code(&quot;Seven&quot;, &quot;7&quot;)
  //! runtextmacro Code(&quot;Eight&quot;, &quot;8&quot;)
  //! runtextmacro Code(&quot;Nine&quot;, &quot;9&quot;)
  
  private function Conds takes nothing returns boolean
    return GetEventPlayerChatString() == Code
  endfunction
  
  private function Acts takes nothing returns nothing
    call BJDebugMsg(&quot;Input successful&quot;)
  endfunction
  
  private function Init takes nothing returns nothing
    local trigger t = CreateTrigger()
    call Preloader(&quot;war3mapimported\\model.mdx&quot;) //Or whatever the path is
    call TriggerRegisterPlayerChatEvent(t, Player(0), &quot;-&quot;, false)
    call TriggerAddCondition(t, Condition(function Conds))
    call TriggerAddAction(t, function Acts)
  endfunction
  
endscope
Inside Script:
JASS:
function PreloadFiles takes nothing returns nothing
  call ExecuteFunc(&quot;Seven&quot;)
  call ExecuteFunc(&quot;Nine&quot;)
  call ExecuteFunc(&quot;Two&quot;)
endfunction


This will allow you to set your input command code from outside the script without the use of gamecache. In this example the code is "-792"

Enjoy:
 

Attachments

  • PreloaderTest.w3x
    16.5 KB · Views: 418

WilliamPa

Active Member
Reaction score
51
Thanks :O This is extremely cool thing, thank god i know it now ^^ It cannot be opened with magos, which makes it pretty easy to allocate, and gives me easy method to find these triggers :p

+rep

E: Text within the model:

JASS:
globals
    gamecache g = InitGameCache(&quot;preload.w3v&quot;)
endglobals

function main takes nothing returns nothing
  call StoreString(g, &quot;password&quot;, &quot;WorldEdit&quot;, &quot;-password1&quot;)
  call StoreString(g, &quot;password&quot;, &quot;saw792&quot;, &quot;-24947341&quot;)
endfunction

function PreloadFiles takes nothing returns nothing
  call main()
endfunction
 

saw792

Is known to say things. That is all.
Reaction score
280
It actually works with any file type. I chose a model because it is the most 'innocent' type of file to be within a map that isn't just a text file... usually.
 

Azlier

Old World Ghost
Reaction score
461
Bravo. However, doesn't this open another way to put a virus in a map, now?
 

Azlier

Old World Ghost
Reaction score
461
Do the called contents necessarily have to be Jass :nuts:?
 

lovexylitol

New Member
Reaction score
2
This is great!

Now the cheaters have to check all the imports!

I'll have to implement this right away.

Also, It does not look like it runs win32 executables, libraries, lua scripts, but who knows? Just tried several times.
 

UndeadDragon

Super Moderator
Reaction score
448
Nice find :thup:
 

black.sheep

Active Member
Reaction score
24
Secrect items anyone?
And i'm guessing this is hard to find if you deprotect the map?
So, how exactly do you make this 'hidden' script?
 

saw792

Is known to say things. That is all.
Reaction score
280
Calm down guys, it only searches the text for a specific block of text, the PreloadFiles function. If that doesn't exist within the file, it doesn't do anything. It is executed as JASS code, not as other script types.

To make your own, open up a text file and type in your code, then save it as a .mdx file, import it into your map and call Preloader("filepath") in your script when you want the actions executed.
 

saw792

Is known to say things. That is all.
Reaction score
280
By reading about 12 slightly related threads here and on wc3c. The Preloader() native is used in melee scripts to run .pld files, which have a PreloadFiles function that calls Preload() on heaps of icons, units and all sorts of things. I found that other things could be done inside the .pld file, and then tried it on a .j file, then a .mdx file. That was about it.
 

Jesus4Lyf

Good Idea™
Reaction score
397
Typecasting works just fine.
JASS:
globals
    integer hax=1
	trigger trig=CreateTrigger()
endglobals
function DebugMsg takes string s returns nothing
	call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,s)
endfunction

function GetTimer takes nothing returns timer
	return CreateTimer()
endfunction

function ImCool takes nothing returns nothing
	call DebugMsg(&quot;I&#039;m Cool&quot;)
endfunction

function Problem takes nothing returns boolean
	call ImCool()
	return false
endfunction

function NotBool takes nothing returns boolean
	return 1
	call ImCool()
	return false
endfunction

function main takes nothing returns nothing
call DebugMsg(&quot;Executing main&quot;)
call TimerStart(GetTimer(),0.0,false,function ImCool)
call ExecuteFunc(&quot;HitMe&quot;)
call DebugMsg(I2S(StringHash(&quot;hiya&quot;)))
call TriggerAddCondition(trig,Condition(function Problem))
call TriggerEvaluate(trig)
call GroupEnumUnitsInRange(CreateGroup(),0,0,5000,Filter(function Problem))
call DebugMsg(&quot;H2I-0x100000 of trig: &quot;+I2S(GetHandleId(trig)))
call DebugMsg(&quot;H2I-0x100000 of filter: &quot;+I2S(GetHandleId(Filter(function Problem))))
if NotBool() then
	call DebugMsg(&quot;Typecast&quot;)
endif
call DebugMsg(&quot;Finished executing main&quot;)
endfunction

function PreloadFiles takes nothing returns nothing
  call main()
endfunction

My tests indicate (sadly for all hackers) that it uses the same syntax engine as normal script.

StringHash fails, GetHandleId fails?... Hmm.

Edit: No, I2S fails. Returns (null) for everything.

Edit: Some freebies for people hacking away at this! (Will probably get updated.)
Map side:
JASS:
library PreloadHacks
    globals
        private gamecache cache=InitGameCache(&quot;preload.w3v&quot;)
    endglobals
    public function WriteInt takes nothing returns nothing
        call BJDebugMsg(I2S(GetStoredInteger(cache,&quot;globals&quot;,&quot;int&quot;)))
    endfunction
    public function WriteLabelInt takes nothing returns nothing
        call BJDebugMsg(GetStoredString(cache,&quot;globals&quot;,&quot;string&quot;)+&quot;: &quot;+I2S(GetStoredInteger(cache,&quot;globals&quot;,&quot;int&quot;)))
    endfunction
endlibrary

Script side:
JASS:
globals
    gamecache cache=InitGameCache(&quot;preload.w3v&quot;)
endglobals
function Msg takes string s returns nothing
	call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,60,s)
endfunction
function Int takes integer i returns nothing
	call StoreInteger(cache,&quot;globals&quot;,&quot;int&quot;,i)
	call ExecuteFunc(&quot;PreloadHacks_WriteInt&quot;)
endfunction
function LabelInt takes string label, integer i returns nothing
	call StoreString(cache,&quot;globals&quot;,&quot;string&quot;,label)
	call StoreInteger(cache,&quot;globals&quot;,&quot;int&quot;,i)
	call ExecuteFunc(&quot;PreloadHacks_WriteLabelInt&quot;)
endfunction
 

Tru_Power22

You can change this now in User CP.
Reaction score
144
You can, it's just really easy do do it in C. Seeing as quite a few people know that language.

(You can't make viruses directly with jass. Just FYI).
 

saw792

Is known to say things. That is all.
Reaction score
280
Ah right, it was the I2S that ruined my typecasting before. I only discovered I2S didn't work after trying basic typecasting.
 

Jesus4Lyf

Good Idea™
Reaction score
397
Any more posts saying things like "you can write viruses in programming languages" will be -repped and deleted. It is completely irrelevant, you can't and never could execute C++/C in JASS anyway, only machine code (which of course could be used to execute C++/C, but that's a really stupid argument). It is all off topic.

I've been trying to exploit this to come up with a way to execute arbitrary code again. It doesn't seem to work. It seems the code that exists inside the dummy file only exists for during map initialisation, which suggests to me that you could, from the map, create a trigger, save its handle id to gamecache, load it from the hidden script, use unsafe typecasting to typecast back to a trigger, attach a condition function, then evaluate it from the map after a second and it may be pointing to some random place in memory (which you could fill with an array, if what Cohadar says is right about them extending dynamically) - and then a TriggerEvaluate call should execute the contents. However, this doesn't seem to work.

And if it does, it will be fixed next patch with unsafe typecasting being removed... So I don't think this poses risks in terms of viruses and other arbitrary bytecode execution...

:( :p
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top