Demo Map Hidden Script

saw792

Is known to say things. That is all.
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

WilliamPa

Active Member
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.
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
Bravo. However, doesn't this open another way to put a virus in a map, now?
 

Azlier

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

lovexylitol

New Member
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
Staff member
Nice find :thup:
 

black.sheep

Active Member
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.
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.
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™
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'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.
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.
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™
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.
  • Ghan Ghan:
    The old shoutbox wasn't supported anymore. We updated xenForo, so it had to be replaced.
  • jonas jonas:
    let's see if everyone finds it... the nice thing about the shoutbox was I could check on it even while logged out, but the existence of this one is hidden when you're not logged in
  • Ghan Ghan:
    We can fix that.
  • Ghan Ghan:
    Chat should show on the sidebar when not logged in now.
  • Ghan Ghan:
    (You'll still need to log in to post messages)
  • Ghan Ghan:
    Test!
  • tom_mai78101 tom_mai78101:
    I must be in a test server.
  • tom_mai78101 tom_mai78101:
    Nice, Twitter tweets embedding now works
  • Wizard Wizard:
    Yup.
  • Ghan Ghan:
    Excellent.
  • Ghan Ghan:
    @tom_mai78101 Hello there.
  • Ghan Ghan:
    Tagging works in the chat too.
  • tom_mai78101 tom_mai78101:
    @Ghan Missed it.
  • Wizard Wizard:
    Still fixing things here and there. Added widgets to the portal, will make it match the ones here on the forum index tomorrow.
  • Ghan Ghan:
    The venerable World Editor Tutorials site has been converted to HTTPS at last.
  • jonas jonas:
    cool
  • jonas jonas:
    and I can even edit my messages, nice
  • seph ir oth seph ir oth:
    GENERAL CHIT CHAT, YOU ARE A BOLD ONE
  • Ghan Ghan:
    Hello there
  • The Helper The Helper:
    this new chatbox is great and the forum software update is great too
    +1
  • The Helper The Helper:
    upgrade has fixed forum registration spam problem
  • tom_mai78101 tom_mai78101:
    Something tells me we might be able to customize the chatbox a bit, considering that there's a gap under every message.
  • Wizard Wizard:
    Going to deploy a fix soon, just had to take some time for myself this weekend.
  • Varine Varine:
    Unbelievable. Time for yourself? How dare you!

    Members online

    No members online now.

    Affiliates

    Hive Workshop
    Top