|
You last visited: Today at 05:39
Advertisement
[RELEASE] Pack Module Fix
Discussion on [RELEASE] Pack Module Fix within the Metin2 PServer Guides & Strategies forum part of the Metin2 Private Server category.
01/06/2015, 06:17
|
#1
|
elite*gold: 0
Join Date: Jul 2009
Posts: 2,471
Received Thanks: 5,622
|
[RELEASE] Pack Module Fix
Hello,
You want to stop people from extracting your client with Python?
It's actually pretty simple but this is a tutorial for advanced users ...
First we need a new pack module:
Code:
bool packExist(char* strFileName)
{
// ÆÄÀ̽㿡¼* Àоîµå¸®´Â ÆÐÅ· ÆÄÀÏÀº python ÆÄÀϰú txt ÆÄÀÏ¿¡ ÇÑÁ¤ÇÑ´Ù
const char* pcExt = strrchr(strFileName, '.');
if (pcExt) // È®ÀåÀÚ°¡ ÀÖ°í
{
if ((stricmp(pcExt, ".py") == 0) ||
//(stricmp(pcExt, ".pyc") == 0) ||
(stricmp(pcExt, ".txt") == 0))
{
return CEterPackManager::Instance().isExist(strFileName);
}
}
return false;
}
PyObject * packImportAsModule(PyObject* poSelf, PyObject * poArgs)
{
char* strFileName;
if (!PyTuple_GetString(poArgs, 0, &strFileName))
return Py_BuildException();
if (packExist(strFileName))
{
CMappedFile file;
const void * pData = NULL;
if (CEterPackManager::Instance().Get(file, strFileName, &pData))
{
PyObject* co = Py_CompileString((const char*)pData, strFileName, Py_file_input);
std::string moduleName = CFileNameHelper::NoExtension(std::string(strFileName));
PyObject* newCo = PyImport_ExecCodeModule(const_cast<char*>(moduleName.c_str()), co);
return Py_BuildValue("S", newCo);
}
}
return Py_BuildValue("b", 0);
}
PyObject * packExist(PyObject * poSelf, PyObject * poArgs)
{
char * strFileName;
if (!PyTuple_GetString(poArgs, 0, &strFileName))
return Py_BuildException();
return Py_BuildValue("i", packExist(strFileName));
}
PyObject * packGet(PyObject * poSelf, PyObject * poArgs)
{
char * strFileName;
if (!PyTuple_GetString(poArgs, 0, &strFileName))
return Py_BuildException();
if (packExist(strFileName))
{
CMappedFile file;
const void * pData = NULL;
if (CEterPackManager::Instance().Get(file, strFileName, &pData) && strlen((const char *)pData) == file.Size())
return Py_BuildValue("s#",pData, file.Size());
}
return Py_BuildException();
}
void initpack()
{
static PyMethodDef s_methods[] =
{
{ "Exist", packExist, METH_VARARGS },
{ "Get", packGet, METH_VARARGS }, // remove this after you implemented everything to load npclist and other files with the binary
{ "ImportAsModule", packImportAsModule, METH_VARARGS },
{ NULL, NULL },
};
Py_InitModule("VFSImporter", s_methods);
}
Now we need to replace
Code:
void CPythonCharacterManager::LoadNPCList()
{
const VOID* pvData;
CMappedFile kFile;
if (!CEterPackManager::Instance().Get(kFile, "npclist.txt", &pvData))
return;
CMemoryTextFileLoader textFileLoader;
textFileLoader.Bind(kFile.Size(), pvData);
CTokenVector TokenVector;
for (uint32_t i = 0; i < textFileLoader.GetLineCount(); ++i)
{
if (!textFileLoader.SplitLineByTab(i, &TokenVector))
continue;
if (TokenVector.size() == 0)
continue;
if (is_number(TokenVector[0]))
{
uint32_t vnum = atoi(TokenVector[0].c_str());
if (vnum > 0)
{
CRaceManager::Instance().RegisterRaceName(vnum, TokenVector[1].c_str());
}
else
{
CRaceManager::Instance().RegisterRaceSrcName(TokenVector[1].c_str(), TokenVector[2].c_str());
}
}
else
{
CRaceManager::Instance().RegisterRaceSrcName(TokenVector[1].c_str(), TokenVector[2].c_str());
}
}
}
CharacterManagerModule:
Add:
Code:
PyObject * chrmgrLoadNPCList(PyObject* poSelf, PyObject* poArgs)
{
CPythonCharacterManager & rkChrMgr = CPythonCharacterManager::Instance();
rkChrMgr.LoadNPCList();
return Py_BuildNone();;
}
and add also:
Code:
{ "LoadNPCList", chrmgrLoadNPCList, METH_VARARGS },
and the system.py
Code:
import sys
import app
import dbg
sys.path.append("lib")
class TraceFile:
def write(self, msg):
dbg.Trace(msg)
class TraceErrorFile:
def write(self, msg):
dbg.TraceError(msg)
dbg.RegisterExceptionString(msg)
class LogBoxFile:
def __init__(self):
self.stderrSave = sys.stderr
self.msg = ""
def __del__(self):
self.restore()
def restore(self):
sys.stderr = self.stderrSave
def write(self, msg):
self.msg = self.msg + msg
def show(self):
dbg.LogBox(self.msg,"Error")
sys.stdout = TraceFile()
sys.stderr = TraceErrorFile()
#
# pack file support (must move to system.py, systemrelease.pyc)
#
import marshal
import imp
import VFSImporter
class pack_file_iterator(object):
def __init__(self, packfile):
self.pack_file = packfile
def next(self):
tmp = self.pack_file.readline()
if tmp:
return tmp
raise StopIteration
_chr = __builtins__.chr
class pack_file(object):
def __init__(self, filename, mode = 'rb'):
assert mode in ('r', 'rb')
if not VFSImporter.Exist(filename):
raise IOError, 'No file or directory'
self.data = VFSImporter.Get(filename)
if mode == 'r':
self.data=_chr(10).join(self.data.split(_chr(13)+_chr(10)))
def __iter__(self):
return pack_file_iterator(self)
def read(self, len = None):
if not self.data:
return ''
if len:
tmp = self.data[:len]
self.data = self.data[len:]
return tmp
else:
tmp = self.data
self.data = ''
return tmp
def readline(self):
return self.read(self.data.find(_chr(10))+1)
def readlines(self):
return [x for x in self]
old_open = open
def open(filename, mode = 'rb'):
if VFSImporter.Exist(filename) and mode in ('r', 'rb'):
return pack_file(filename, mode)
else:
return old_open(filename, mode)
__builtins__.open = open
__builtins__.pack_open = pack_open = pack_file
_ModuleType = type(sys)
old_import = __import__
module_do = lambda x:None
def __hybrid_import(name,globals=None,locals=None,fromlist=None, level=-1):
filename = name + '.py'
if VFSImporter.Exist(filename):
if name in sys.modules:
dbg.Tracen('importing from sys.modules %s' % name)
return sys.modules[name]
dbg.Tracen('importing from pack %s' % name)
my_module = VFSImporter.ImportAsModule(filename)
if not my_module:
dbg.TraceError('importing from pack %s failed!' % name)
return my_module
else:
dbg.Tracen('importing from lib %s' % name)
return old_import(name,globals,locals,fromlist, level)
def splitext(p):
root, ext = '', ''
for c in p:
if c in ['/']:
root, ext = root + ext + c, ''
elif c == '.':
if ext:
root, ext = root + ext, c
else:
ext = c
elif ext:
ext = ext + c
else:
root = root + c
return root, ext
def __IsCompiledFile__(sFileName):
sBase, sExt = splitext(sFileName)
sExt=sExt.lower()
if sExt==".pyc" or sExt==".pyo":
return 1
else:
return 0
def __LoadTextFile__(sFileName):
sText=open(sFileName,'r').read()
return compile(sText, sFileName, "exec")
def __LoadCompiledFile__(sFileName):
kFile=open(sFileName)
if kFile.read(4)!=imp.get_magic():
raise
kFile.read(4)
kData=kFile.read()
return marshal.loads(kData)
def execfile(fileName, dict):
if __IsCompiledFile__(fileName):
code=__LoadCompiledFile__(fileName)
else:
code=__LoadTextFile__(fileName)
exec code in dict
import __builtin__
__builtin__.__import__ = __hybrid_import
# cython의 버그로... 외부 모듈의 __dict__를 수정하여, 모듈에 원래 있는 object를 수정해봐야 해당 모듈 내에서 바뀐 object가 적용되지 않는다.
# module_do는 외부 모듈의 execfile object를 __builtin__.execfile에서 system.execfile로 치환하는 작업을 하는데 공염불이다...(외부 모듈은 __builtin__.execfile을 쓸 뿐이다.)
# 따라서 __builtin__.execfile을 system.execfile로 치환해버림...
#module_do = exec_add_module_do
__builtin__.execfile = execfile
def GetExceptionString(excTitle):
(excType, excMsg, excTraceBack)=sys.exc_info()
excText=""
excText+=_chr(10)
import traceback
traceLineList=traceback.extract_tb(excTraceBack)
for traceLine in traceLineList:
if traceLine[3]:
excText+="%s(line:%d) %s - %s" % (traceLine[0], traceLine[1], traceLine[2], traceLine[3])
else:
excText+="%s(line:%d) %s" % (traceLine[0], traceLine[1], traceLine[2])
excText+=_chr(10)
excText+=_chr(10)
excText+="%s - %s:%s" % (excTitle, excType, excMsg)
excText+=_chr(10)
return excText
def ShowException(excTitle):
excText=GetExceptionString(excTitle)
dbg.TraceError(excText)
app.Abort()
return 0
def RunMainScript(name):
try:
execfile(name, __main__.__dict__)
except RuntimeError, msg:
msg = str(msg)
import localeInfo
if localeInfo.error:
msg = localeInfo.error.get(msg, msg)
dbg.LogBox(msg)
app.Abort()
except:
msg = GetExceptionString("Run")
dbg.LogBox(msg)
app.Abort()
import debugInfo
debugInfo.SetDebugMode(__DEBUG__)
loginMark = "-cs"
app.__COMMAND_LINE__ = __COMMAND_LINE__
RunMainScript("prototype.py")
Search:
Code:
def __LoadGameNPC():
Replace the whole function:
Code:
def __LoadGameNPC():
chrmgr.LoadNPCList()
If your python code does not load any files with pack_open or pack.Get you can remove the pack.Get function.
|
|
|
01/06/2015, 08:49
|
#2
|
elite*gold: 300
Join Date: Apr 2013
Posts: 3,234
Received Thanks: 1,205
|
Das ist der Fix für den Stuff den xGr33n und GayFox released haben?
|
|
|
01/06/2015, 08:55
|
#3
|
elite*gold: 0
Join Date: Jul 2009
Posts: 2,471
Received Thanks: 5,622
|
Im Grunde schon genau genommen wenn man es richtig macht ein Fix für das entpacken über Python Allgemein
|
|
|
01/06/2015, 09:01
|
#4
|
Trade Restricted
elite*gold: 9
Join Date: Jul 2014
Posts: 818
Received Thanks: 677
|
Habs mir nicht genau angeguckt, aber die pack_open Funktion und das pack modul sind 2 verschiedene paar Schuhe, solltest du dich also nicht an die open Funktion gesetzt haben (habs mir ehrlich gesagt nicht angeguckt) bringt das ganze hier nichts
|
|
|
01/06/2015, 09:26
|
#5
|
elite*gold: 0
Join Date: Jul 2009
Posts: 2,471
Received Thanks: 5,622
|
Quote:
Originally Posted by grαyfox
Habs mir nicht genau angeguckt, aber die pack_open Funktion und das pack modul sind 2 verschiedene paar Schuhe, solltest du dich also nicht an die open Funktion gesetzt haben (habs mir ehrlich gesagt nicht angeguckt) bringt das ganze hier nichts
|
pack_open benutzt lustigerweise pack.Get oder wie die Funktion halt im Client des nennen wir es mal Ziels heißt ... also ist deine Aussage schon mal im Kern falsch.
Ich habe einen weg aufgezeigt bei dem keine absolut pack.Get Methode mehr benötigt wird wodurch auch die pack_open Funktion nicht mehr benötigt wird wodurch wie bereits erwähnt es nicht mehr möglich ist Dateien über Python zu entpacken.
Python Dateien werden mit dem Weg oben direkt importiert und nicht erst später in Python verarbeitet.
Die Open Funktion ist im anderen Thema sollte ein funktionierender Fix sein
|
|
|
01/06/2015, 11:35
|
#6
|
elite*gold: 5
Join Date: Mar 2013
Posts: 1,986
Received Thanks: 2,254
|
Nana Nova... wenn das in AoZ schon drin war, denn dort hieß das packmodul genauso, hat es nichts genuetzt, wenn nicht, nettes release  Achso für die Person die gefragt hat ob das der fix für beides ist: Nö
€: Ich bin mir nicht ganz sicher aber soweit ich das gesehen hab' wird der Client nicht funktionieren wenn ihr die .Get Funktion rausnehmt
|
|
|
01/06/2015, 12:57
|
#7
|
elite*gold: 2
Join Date: Jan 2010
Posts: 422
Received Thanks: 1,160
|
Quote:
|
€: Ich bin mir nicht ganz sicher aber soweit ich das gesehen hab' wird der Client nicht funktionieren wenn ihr die .Get Funktion rausnehmt
|
Deshalb hat er ja dazu geschrieben:
Quote:
|
If your python code does not load any files with pack_open or pack.Get you can remove the pack.Get function.
|
Aber ja. mit der npclist allein ist das nicht erledigt. Dazu kommen noch die locale's (locale_game, locale_interface) und vor allem die UIScripts und die loginInfo.
Die locales sollte man von der bin laden lassen(wie oben die npclist). Außerdem sollte noch execfile() komplett in die bin verlagert werden.
|
|
|
01/06/2015, 17:12
|
#8
|
elite*gold: 20
Join Date: Jun 2011
Posts: 2,901
Received Thanks: 3,341
|
Quote:
Originally Posted by xGr33n
Nana Nova... wenn das in AoZ schon drin war, denn dort hieß das packmodul genauso, hat es nichts genuetzt, wenn nicht, nettes release  Achso für die Person die gefragt hat ob das der fix für beides ist: Nö
€: Ich bin mir nicht ganz sicher aber soweit ich das gesehen hab' wird der Client nicht funktionieren wenn ihr die .Get Funktion rausnehmt 
|
Also erstmal laberst du Müll.
Sorry, aber die pack_open function an sich ist wenn man es genau nimmt ne Class in der System.py.
Code:
__builtins__.pack_open = pack_open = pack_file
Da wird das ganze definiert.
pack_file ist ne Python Class:
Code:
class pack_file(object):
def __init__(self, filename, mode = 'rb'):
assert mode in ('r', 'rb')
if not pack.Exist(filename):
raise IOError, 'No file or directory'
self.data = pack.Get(filename)
if mode == 'r':
self.data=_chr(10).join(self.data.split(_chr(13)+_chr(10)))
def __iter__(self):
return pack_file_iterator(self)
def read(self, len = None):
if not self.data:
return ''
if len:
tmp = self.data[:len]
self.data = self.data[len:]
return tmp
else:
tmp = self.data
self.data = ''
return tmp
def readline(self):
return self.read(self.data.find(_chr(10))+1)
def readlines(self):
return [x for x in self]
und darin läuft alles über die oben genannten pack.Exists und pack.Get.
nimmt man das oben genannte Beispiel und ersetzt die pack functions mit den obrigen, dann hat man keine Probleme mehr mit eurem Tool.
|
|
|
01/06/2015, 17:54
|
#9
|
elite*gold: 5
Join Date: Mar 2013
Posts: 1,986
Received Thanks: 2,254
|
"Achso für die Person die gefragt hat ob das der fix für beides ist: Nö"
"beides"
Das Release ändert rein gar nichts, was für das andere Script relevant ist:
"soweit ich das gesehen hab' wird der Client nicht funktionieren wenn ihr die .Get Funktion rausnehmt"
die Get Funktion des Packmodules.
Dass pack_open eine Klasse ist mir bewusst. Davon abgesehen pack_open habe ich NIE angesprochen
|
|
|
01/06/2015, 18:04
|
#10
|
elite*gold: 0
Join Date: Jul 2009
Posts: 2,471
Received Thanks: 5,622
|
Code:
PyObject* appLoadLocaleInterface(PyObject* poSelf, PyObject* poArgs)
{
PyObject* dict;
PyArg_ParseTuple(poArgs, "O!", &PyDict_Type, &dict);
const VOID* pvData;
CMappedFile kFile;
std::string localePath = std::string(LocaleService_GetLocalePath());
if (!CEterPackManager::Instance().Get(kFile, (localePath + "locale_interface.txt").c_str(), &pvData))
return;
CMemoryTextFileLoader textFileLoader;
textFileLoader.Bind(kFile.Size(), pvData);
CTokenVector TokenVector;
for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i)
{
if (!textFileLoader.SplitLineByTab(i, &TokenVector))
continue;
if (TokenVector.size() == 0)
continue;
if (TokenVector.size()>=2)
{
PyDict_SetItemString(dict, TokenVector[0].c_str(), PyString_FromString(TokenVector[1].c_str()));
}
}
return Py_BuildNone();
}
Next, es ist wie gesagt möglich das keine Dateien über pack_open oder packGet geladen werden. Aber ich gebe euch hier nicht alles was ihr da für braucht fertig nur das Wissen wie man es macht und das es eben möglich ist.
und wie bereits gesagt wegen der anderen Sache kann man immer noch open überschreiben
Code:
def custom_open(name, mode='r', buffering = 0)
//do stuff to block access to certain files or paths here
return __builtin__.open(path, mode, buffering)
__builtin__.open = custom_open
|
|
|
01/06/2015, 18:54
|
#11
|
elite*gold: 20
Join Date: Jun 2011
Posts: 2,901
Received Thanks: 3,341
|
Quote:
Originally Posted by .Alpha.
Code:
PyObject* appLoadLocaleInterface(PyObject* poSelf, PyObject* poArgs)
{
PyObject* dict;
PyArg_ParseTuple(poArgs, "O!", &PyDict_Type, &dict);
const VOID* pvData;
CMappedFile kFile;
std::string localePath = std::string(LocaleService_GetLocalePath());
if (!CEterPackManager::Instance().Get(kFile, (localePath + "locale_interface.txt").c_str(), &pvData))
return;
CMemoryTextFileLoader textFileLoader;
textFileLoader.Bind(kFile.Size(), pvData);
CTokenVector TokenVector;
for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i)
{
if (!textFileLoader.SplitLineByTab(i, &TokenVector))
continue;
if (TokenVector.size() == 0)
continue;
if (TokenVector.size()>=2)
{
PyDict_SetItemString(dict, TokenVector[0].c_str(), PyString_FromString(TokenVector[1].c_str()));
}
}
return Py_BuildNone();
}
Next, es ist wie gesagt möglich das keine Dateien über pack_open oder packGet geladen werden. Aber ich gebe euch hier nicht alles was ihr da für braucht fertig nur das Wissen wie man es macht und das es eben möglich ist.
und wie bereits gesagt wegen der anderen Sache kann man immer noch open überschreiben
Code:
def custom_open(name, mode='r', buffering = 0)
//do stuff to block access to certain files or paths here
return __builtin__.open(path, mode, buffering)
__builtin__.open = custom_open
|
Alpha das mit dem custom_open bastel ich grade direkt in der exe.
Mit ner tollen Überprüfung, dass nur .txt geladen werden können.
|
|
|
 |
Similar Threads
|
[RELEASE] Python-Module + Funktionen
09/25/2017 - Metin2 PServer Guides & Strategies - 15 Replies
Moin,
ich dachte mir mal, ich trete in die Fußstapfen von hier mehr oder weniger bekannten Mitgliedern (hier ihre Namen verschlüsselt: CxxP & LaSor) und release was, das ich innerhalb von 5 Minuten bekommen kann.
Und zwar:
Eine vollständige Liste ALLER Module und zugehörigen Funktionen in der Metin2-Binary
Die Binary ist von 2010, da ich aber nicht länger als 5 Minuten brauchen darf, konnte ich die neueren Sachen alle noch nicht extracten. Werde ich nachliefern, sobald die gewünschte...
|
[RELEASE]Nonplayer Module Happy New Year!!!
10/20/2014 - Metin2 PServer Guides & Strategies - 19 Replies
http://grabilla.com/03c15-00461f51-c581-4900-a3b4- b02e3c197710.png
import ui
import playerSettingModule
import chr
import app
import grp
import player
import background
import constInfo
|
[Release] Very simple PHP module for server stats
05/09/2012 - SRO Coding Corner - 25 Replies
Hello, this is my first 'release' in a very long time at EPVP. As you know I gave up long ago trying to participate actively and showing my stuff because of the community actitude. I am not that faithful anymore.
However, here I bring a very little script that I think will be useful. Having a look at all server's websites which has been released and those who I got access by other ways I have realized all of them are using the socket connections, along with handshake drama.
The main...
|
[Mini Release]Skill Module Adition
01/18/2012 - Metin2 PServer Guides & Strategies - 5 Replies
Vorgeschichte:
Joa da ich neulich mal meine Scripts wieder angeschaut hatte hab ich mitbekommen, dass ich die Skill Icons einfach nur nooblike dargestellt habe.
Daraufhin hab ich mir ein kleines Script gemacht, welches mir die Icons ausgibt.
Verwenden tut ihr das Script folgendermaßen:
Ihr haut die .pyc Datei einfach in den Lib Ordner und addet dort wo ihr es nutzen wollt das hier:
import skilladition
SkillAditionByMeLol = skilladition.SkillAditionDialog()
Nun könnt ihr diese...
|
[Release] Fastject Module Injector
10/14/2011 - Coding Releases - 4 Replies
Hey,
hier mal ein etwas älterer Injector von mir.
Features:
2 different injection methods (CreateRemoteThread and SetThreadContext)
module hiding via PEB manipulation
auto save / load settings
manual injection by process id
|
All times are GMT +1. The time now is 05:39.
|
|