-

   rss_rss_hh_new

 - e-mail

 

 -

 LiveInternet.ru:
: 17.03.2011
:
:
: 51

:


[ ] maphack

, 26 2017 . 13:34 +
EvilWind 13:34

maphack

image


, DayZ Mod (Arma 2 OA). , , Battleye , , , .


DayZ , , ( , ). .


.


1.


, . . , , .


1


, Ubuntu CyberPack (IRF) fmem, , fmem .
, LiME ~ Linux Memory Extractor. livecd.
TinyCore(TinyCorePure64, 3 ). .


tce-load -iw linux-kernel-sources-env.tcz
cliorx linux-kernel-sources-env.sh

, , make


insmod ./lime.ko "path=/path/mem-image.lime format=lime"

- , . Volatility Framework memdump.


vol.py -f F:\mem-image.lime format=lime pslist
vol.py -f F:\mem-image.lime format=lime memdump dump-dir ./output p 868

Rekall Framework, , volatility


rekal -f F:\mem-image.lime pslist
rekal -f F:\mem-image.lime memdump dump_dir="./output", pids=868

, .


Rekall windows 10, - :


WARNING:rekall.1:Profile nt/GUID/F6F4895554894B24B4DF942361F0730D1 fetched and built. Please consider reporting this profile to the Rekall team so we may add it to the public profile repository.

, :


CRITICAL:rekall.1:A DTB value was found but failed to verify. See logging messages for more information.

, --profile , .


2


hiberfil.sys, .


, , livecd ( , - TinyCore), (Read-Only) , .


TinyCore ntfs.


tce-load -iw ntfs-3g

fdisk -l,


sudo ntfs-3g -o ro /dev/sda2 /tmp/a1  //   Read-Only
sudo ntfs-3g /dev/sdc1 /tmp/a2


cp /tmp/a1/hiberfil.sys /tmp/a2

volatility ( win7 ).


vol.py imagecopy -f hiberfil.sys -O win7.img

win10, .
Hibr2bin, Sandman Framework.


HIBR2BIN /PLATFORM X64 /MAJOR 10 /MINOR 0 /INPUT hiberfil.sys /OUTPUT uncompressed.bin

output, .
Hibernation Recon Free , .
memdump .


File Address      Length      Virtual Addr
-------------- -------------- --------------
0x000000000000 0x000000001000 0x000000010000
0x000000001000 0x000000001000 0x000000020000
0x000000002000 0x000000001000 0x000000021000
0x000000003000 0x000000001000 0x00000002f000
0x000000004000 0x000000001000 0x000000040000
0x000000005000 0x000000001000 0x000000050000
0x000000006000 0x000000001000 0x000000051000

2. .


GUI Qt.


.


class MemoryAPI
{
public:
    MemoryAPI(){}
    MemoryAPI(QString pathDump, QString pathIDX);
    //     
    quint32 readPtr      (const quint32 offset);
    qint32  readInt      (const quint32 offset);
    float   readFloat    (const quint32 offset);
    QString readStringAscii(const quint32 offset, const quint32 size);
    QString readArmaString(quint32 offset);
    // 
    void loadIDX        (QString path);
    void loadDump       (QString path);

private:
    //      
    QVector  memoryRelations;
    quint32 convertVirtToPhys(const quint32 virt) const;
    QByteArray readVirtMem(const quint32 baseAddr, const quint32 size);
    QFile dumpFile;
};

idx- .


class MemoryRange
{
private:
    quint32 baseVirtualAddress;
    quint32 basePhysicalAddress;
    quint32 size;
};

.


QByteArray MemoryAPI::readVirtMem(const quint32 baseAddr, const quint32 size)
{
    QByteArray result;
    // 
    quint32 addr = convertVirtToPhys(baseAddr);
    dumpFile.seek(addr);
    result = dumpFile.read(size);

    return result;
}

( , ).


quint32 MemoryAPI::convertVirtToPhys(const quint32 virt) const
{
    for(auto it = memoryRelations.begin(); it != memoryRelations.end(); ++it)
    {
        if((*it).inRange(virt))
        {
            const quint32& phBase = (*it).getPhysicalAddress(), vrBase = (*it).getVirtualAddress();
            //  
            if(phBase>vrBase)
                return virt + (phBase - vrBase);
            else
                return virt - (vrBase - phBase);
        }
    }
    //      
    throw 1;
}

, .


class EntityData
{
public:
    friend class WorldState;
    //     
    enum class type {airplane, car, motorcycle, ship, helicopter, parachute, tank,
                     tent, stash, fence, ammoBox, campFire, crashSite, animals,
                     players, zombies, stuff, hedgehog, invalid};

    type entityType;

    EntityData();
    EntityData(QString n, QPointF c, type t = type::stuff);

    QString shortDescription()const;
    QString fullDescription()const;
    QPointF getCoords() const {return coords;}
private:
    // 
    QString name;
    // 
    QPointF coords;
    //    ( )
    QMap additionalFields;
};

, ( ).


class WorldState
{
public:
    //    ,    
    WorldState(const QString& dumpFile, const QString& idxFile);
    //  xml-   
    WorldState(const QString& stateFile);
    // xml-,     
    void saveState(const QString& stateFile);
    // ,          ( )
    QMap  entityRanges;
    QString worldName;
private:
    //   
    QVector  entityArray;
        //    
    QVector masterOffsets;
    QVector tableOffsets;
    quint32          objTableAddress;
    void handleEntity   (quint32 entityAddress, MemoryAPI& mem);
        //
    void initRanges();
    void initOffsets();

    QDomElement makeElement(QDomDocument& domDoc, const QString& name, const QString& strData = QString());
};

.


WorldState::WorldState(const QString& dumpFile, const QString& idxFile)
{
    // 
    initOffsets();

    //     
    QProgressDialog progress;
    progress.setCancelButton(nullptr);
    progress.setLabelText("Loading dump...");
    progress.setModal(true);
    progress.setMinimum(0);

    progress.setMaximum(masterOffsets.length()+2);
    progress.show();

    MemoryAPI mem(dumpFile,idxFile);
    progress.setValue(1);

    for(auto mO = masterOffsets.begin(); mO != masterOffsets.end(); ++mO)
    {
        quint32 entityTableBasePtr = mem.readPtr(objTableAddress) + (*mO);
        for(auto tO = tableOffsets.begin(); tO != tableOffsets.end(); ++tO)
        {
            qint32 size = mem.readInt(entityTableBasePtr + 0x4 +(*tO));

            for(qint32 i = 0; i!=size; ++i)
            {
                quint32 fPtr = mem.readPtr(entityTableBasePtr + (*tO));
                quint32 entityAddress = mem.readPtr(fPtr + 4 * i);

                // 
                handleEntity(entityAddress, mem);

                //   ,      
                QCoreApplication::processEvents();
            }
        }
        progress.setValue(progress.value()+1);
    }
    initRanges();
    worldName = "chernarus";
    progress.setValue(progress.value()+1);
}


void WorldState::initOffsets()
{
    masterOffsets.append(0x880);
    masterOffsets.append(0xb24);
    masterOffsets.append(0xdc8);

    tableOffsets.append(0x8);
    tableOffsets.append(0xb0);
    tableOffsets.append(0x158);
    tableOffsets.append(0x200);

    objTableAddress = 0xDAD8C0;
}

. ( , ).


class World
{
public:
char _0x0000[8];
    InGameUI* inGameUI; //0x0008 
char _0x000C[1520];
    EntityTablePointer* entityTablePointer; //0x05FC 
    VariableTableInfo* variableTableInfo; //0x0600 
char _0x0604[428];
    __int32 gameMode; //0x07B0 
char _0x07B4[4];
    float speedMultiplier; //0x07B8 
char _0x07BC[196];
        EntitiesDistributed table1; //0x0880
char _0x0B00[36];
    EntitiesDistributed table2; //0x0B24
char _0x0DA4[36];
    EntitiesDistributed table3; //0x0DC8
char _0x1048[849];
    BYTE artilleryEnabled; //0x1399 
    BYTE enableItemsDropping; //0x139A 
char _0x139B[13];
    UnitInfo* cameraOn; //0x13A8 
char _0x13AC[4];
    UnitInfo* cplayerOn; //0x13B0 
    UnitInfo* realPlayer; //0x13B4 
char _0x13B8[48];
    float actualOvercast; //0x13E8 
    float wantedOvercast; //0x13EC 
    __int32 nextWeatherChange; //0x13F0 
    float currentFogLevel; //0x13F4 
    float fogTarget; //0x13F8 
char _0x13FC[32];
    __int32 weatherTime; //0x141C 
char _0x1420[8];
    BYTE playerManual; //0x1428 
    BYTE playerSuspended; //0x1429 
char _0x142A[30];
    __int32 N0D09AD19; //0x1448 
char _0x144C[92];
    ArmaString* currentCampaign; //0x14A8 
char _0x14AC[4];
    __int32 N0D09B79F; //0x14B0 
char _0x14B4[52];
    float viewDistanceHard; //0x14E8 
    float viewDistanceMin; //0x14EC 
    float grass; //0x14F0 
char _0x14F4[36];
    __int32 initTableCount; //0x1518 
    __int32 initTableMaxCount; //0x151C 
char _0x1520[4];

};//Size=0x1524

, ( , ). objTableAddress. masterOffsets 3 , .


class EntitiesDistributed
{
public:
char _0x0000[8];
    Entity* table1; //0x0008
    __int32 table1Size; //0x000C 
char _0x0010[160];
    Entity* table2; //0x00B0
    __int32 table2Size; //0x00B4 
char _0x00B8[160];
    Entity* table3; //0x0158
    __int32 table3Size; //0x015C 
char _0x0160[160];
    Entity* table4; //0x0200
    __int32 table4Size; //0x0204 
char _0x0208[120];

};//Size=0x0280

4 ( tableOffsets).
. , .


void WorldState::handleEntity(quint32 entityAddress, MemoryAPI &mem)
{
    QString objType;
    QString objName;
    float coordX;
    float coordY;

    try{
        quint32 obj1 = entityAddress;
        quint32 pCfgVehicle = mem.readPtr(obj1 + 0x3C);
        quint32 obj3 = mem.readPtr(pCfgVehicle + 0x30);
        quint32 pObjType = mem.readPtr(pCfgVehicle + 0x6C);

        objType = mem.readArmaString(pObjType);
        objName = mem.readStringAscii(obj3 + 0x8, 25);

        quint32 pEntityVisualState = mem.readPtr(obj1 + 0x18);
        coordX = mem.readFloat(pEntityVisualState + 0x28);
        coordY = mem.readFloat(pEntityVisualState + 0x30);
    }catch(int a)
    {
        qDebug() << "    .";
        return;
    }

    //  
    EntityData ed(objName, QPointF(coordX, coordY));

    //   
    if(objType == "car")
        ed.entityType = EntityData::type::car;
    else if(objType == "motorcycle")
        ed.entityType = EntityData::type::motorcycle;
    else if(objType == "airplane")
        ed.entityType = EntityData::type::airplane;
    else if(objType == "helicopter")
        ed.entityType = EntityData::type::helicopter;
    else if(objType == "ship")
        ed.entityType = EntityData::type::ship;
    else if(objType == "tank")
        ed.entityType = EntityData::type::tank;
    else if(objType == "parachute")
        ed.entityType = EntityData::type::parachute;
    else if(objName.indexOf("TentStorage")!=-1)
        ed.entityType = EntityData::type::tent;
    else if(objName.indexOf("Stash")!=-1)
        ed.entityType = EntityData::type::stash;
    else if(objName.indexOf("WoodenGate")!=-1 || objName.indexOf("WoodenFence")!=-1)
        ed.entityType = EntityData::type::fence;
    else if(objName.indexOf("DZ_MedBox")!=-1 || objName.indexOf("DZ_AmmoBox")!=-1)
        ed.entityType = EntityData::type::ammoBox;
    else if(objName.indexOf("Hedgehog_DZ")!=-1)
        ed.entityType = EntityData::type::hedgehog;
    else if(objName.indexOf("Land_Camp_Fire_DZ")!= -1)
        ed.entityType = EntityData::type::campFire;
    else if(objName.indexOf("CrashSite")!= -1)
        ed.entityType = EntityData::type::crashSite;
    else if(objName.indexOf("WildBoar")== 0 || objName.indexOf("Rabbit")== 0 ||
            objName.indexOf("Cow")== 0 || objName.indexOf("Sheep")== 0 ||
            objName.indexOf("Goat")== 0 || objName.indexOf("Hen")== 0)
        ed.entityType = EntityData::type::animals;
    else if(objName.indexOf("Survivor2_DZ")!= -1 || objName.indexOf("Sniper1_DZ")!=-1 ||
            objName.indexOf("Camo1_DZ")!=-1 || objName.indexOf("Survivor3_DZ")!=-1 ||
            objName.indexOf("Bandit1_DZ")!= -1 || objName.indexOf("Soldier1_DZ")!= -1)
        ed.entityType = EntityData::type::players;
    else
        ed.entityType = EntityData::type::stuff;

    entityArray.append(ed);
}


class Entity
{
public:
char _0x0000[24];
    EntityVisualState* entityVisualState; //0x0018 
char _0x001C[32];
    CfgVehicle* cfgVehicle; //0x003C 
char _0x0040[476];
    EntityInventory* entityInventory; //0x021C 

};//Size=0x0220

.


  • EntityVisualState .
  • CfgVehicle (, , ..).
  • EntityInventory ( , .. ).


CfgVehicle .


ArmaString* entityName; //0x0030 
ArmaString* objectType; //0x006C 

EntityVisualState
class EntityVisualState
{
public:
char _0x0000[4];
    D3DXVECTOR3 dimension; //0x0004 
    D3DXVECTOR3 rotation1; //0x0010 
    D3DXVECTOR3 direction; //0x001C 
    D3DXVECTOR3 coordinates; //0x0028 
char _0x0034[20];
    D3DXVECTOR3 velocity; //0x0048 
    float angularVelocity; //0x0054 
    float zVelocity2; //0x0058 
    float Speed; //0x005C 
    D3DXVECTOR3 acceleration; //0x0060 
char _0x006C[16];
    D3DXVECTOR3 direction2; //0x007C 
    D3DXVECTOR3 rotation2; //0x0088 
    D3DXVECTOR3 direction3; //0x0094 
char _0x00A0[12];
    float fuelLevel; //0x00AC 
char _0x00B0[92];
    D3DXVECTOR3 headCoordinates; //0x010C 
    D3DXVECTOR3 torsoCoordinates; //0x0118 
char _0x0124[244];
    float N047F1D6C; //0x0218 
char _0x021C[200];

};//Size=0x02E4

EntityVisualState , .


D3DXVECTOR3 coordinates;

struct D3DXVECTOR3 {
  FLOAT x;
  FLOAT y;
  FLOAT z;
};

x y( z), :


coordX = mem.readFloat(pEntityVisualState + 0x28);
coordY = mem.readFloat(pEntityVisualState + 0x30);

, additionalFields, EntityData, . , .


, - , QPainter.


.


class InteractiveMap : public QWidget
{
    Q_OBJECT

public:
    InteractiveMap(QWidget* pwgt = nullptr);
    virtual ~InteractiveMap();

protected:
    virtual void paintEvent(QPaintEvent* pe);

private:
    // (  )
    const float minScale = 1.0f;
    const float maxScale = 8.0f;
    const float scaleStep= 2.0f;

    void updateScale(const qreal value, const QPointF& dpos);
    void updateTranslate(const QPointF& value);

    bool getFilterValue(EntityData::type t);
    bool getFilterValue(QString t);

    void mousePressEvent  (QMouseEvent* pe);
    void mouseMoveEvent   (QMouseEvent* pe);
    void wheelEvent       (QWheelEvent *pe);

    void findCloseObjects(QPointF coords);
    QVector* input;

    QPainter*   painter;
    QPixmap*    image;
    WorldState* worldState;

    qreal scale;
    QPointF translate;
    QPoint startMove;

    // 
    QPixmap cache;

    QMutex renderMutex;

    //  ,   
    QFutureWatcher closeObjWatcher;
    QFuture closeObjFuture;

public slots:
    // 
    void loadState(QString stateFile);
    void loadDump(QString dumpFile, QString idxFile);

    void closeState();
    void saveState(QString stateFile);
    void updateCache();
    void sendCloseObjects();

signals:
    void showCloseObjects(QString str);
    void saveStateChanged(bool state);
};

. QPixmap ( ).


void InteractiveMap::paintEvent(QPaintEvent *pe)
{
    renderMutex.lock();
    painter->begin(this);
//////////////////////////////////////////////////
    QTransform mat;
    painter->setTransform(mat);
    painter->scale(scale, scale);
    painter->translate(translate);
    painter->drawPixmap(0,0, *image);

    if(cache.isNull())
    {
        //  DPR,       
        cache = QPixmap(image->size()*4);
        cache.setDevicePixelRatio(4);
        cache.fill(Qt::transparent);
        QPainter cachePaint(&cache);
        //    
        for(QMap::const_iterator it = worldState->entityRanges.cbegin(); it!=worldState->entityRanges.cend();++it)
        {
            //     
            if(getFilterValue(it.key()))
            {
                for(QVector::const_iterator i = it.value().start; i!= it.value().end; ++i)
                {
                    float x = i->getCoords().x();
                    float y = i->getCoords().y();

                    //    
                    x = (((x) / (15360.0f / 975.0f)));
                    y = (((15360.0f - y) / (15360.0f / 970.0f)) - 4.0f);

                    // 
                    QFont font("Arial");
                    QPen  pen;
                    pen.setWidthF(4.0f/scale);
                    pen.setStyle(Qt::SolidLine);
                    font.setPointSizeF(qMax(float(8.0f*1.0f/scale),2.0f));
                    cachePaint.setFont(font);
                    cachePaint.setPen(pen);
                    cachePaint.drawPoint(x,y);

                    //  ,  
                    if(getFilterValue(QString("name")))
                        cachePaint.drawText(x,y,i->shortDescription());

                }
            }
        }
    }
    painter->drawPixmap(0,0,cache);
//////////////////////////////////////////////////
    painter->end();
    renderMutex.unlock();
}

, , QCheckBox- ( ). , QSettings, , , , , .


class SettingsManager : public QObject
{
    Q_OBJECT
public:
    SettingsManager();
    ~SettingsManager();
    static SettingsManager& instance();
    QVariant value(const QString &key, const QVariant &defaultValue = QVariant());
    void setValue(const QString &key, const QVariant &value);

    SettingsManager(SettingsManager const&) = delete;
    SettingsManager& operator= (SettingsManager const&) = delete;
private:
    QMap data;
    QSettings settings;
signals:
    void updateMap();
};

( ) ( -). ( ).


//  
void InteractiveMap::updateScale(qreal value, const QPointF& dpos)
{
    qreal newScale = scale * value;
    if(newScale >= minScale && newScale <= maxScale)
    {
        scale = newScale;
        //      
        translate += dpos/scale;
        updateCache();
    }
}

//  
void InteractiveMap::updateTranslate(const QPointF& value)
{
    QPointF newV = translate + (value * 1/scale);
    translate = newV;
    update();
}

//   
void InteractiveMap::mousePressEvent(QMouseEvent *pe)
{
    //   
    if(pe->buttons() & Qt::LeftButton)
        startMove = pe->pos();
    //      
    else if(pe->buttons() & Qt::MidButton)
    {
        if(worldState)
        {
            //   ,   
            QPointF pos = pe->pos()/scale - translate;
            if(pos.x() >= 0.0f && pos.x() <= image->width() && pos.y() >= 0.0f && pos.y() <= image->height())
            {
                //    
                pos.rx() = pos.x() * (15360.0f / 975.0f);
                pos.ry() = -((15360.0f/970.0f)*(pos.y()+4.0f)-15360.0f);
                //  
                findCloseObjects(pos);
            }
        }

    }
}

void InteractiveMap::mouseMoveEvent(QMouseEvent *pe)
{
    //   
    if(pe->buttons() & Qt::LeftButton)
    {
        updateTranslate(pe->pos() - startMove);
        startMove = pe->pos();
    }
}

void InteractiveMap::wheelEvent(QWheelEvent *pe)
{
    // 
    float dScale = (pe->angleDelta().y() < 0) ? 1/scaleStep : scaleStep;

    QPointF nPos = pe->pos() * (dScale);
    QPointF dPos = pe->pos() - nPos;

    updateScale(dScale,dPos);
}

QtConcurrent, MapReduce.


//Reduce 
void addToAnswer(QString& result, const QString& interm)
{
    if(!interm.isEmpty())
        result += interm;
}

void InteractiveMap::findCloseObjects(QPointF coords)
{
    if(!closeObjWatcher.isRunning())
    {
        //  
        input = new QVector;
        for(QMap::iterator it = worldState->entityRanges.begin(); it!=worldState->entityRanges.end();++it)
        {
            if(getFilterValue(it.key()))
            {
                //  
                CloseObjects obj(&it.value(), coords);
                input->append(obj);
            }
        }
        closeObjFuture = QtConcurrent::mappedReduced(*input, &CloseObjects::findCloseObjects, addToAnswer);
        //    
        connect(&closeObjWatcher, &QFutureWatcher::finished, this, &InteractiveMap::sendCloseObjects);
        // 
        closeObjWatcher.setFuture(closeObjFuture);
    }
}

void InteractiveMap::sendCloseObjects()
{
    //   
    emit showCloseObjects(closeObjWatcher.result());
    //    
    delete input;
    input = nullptr;
}

.


class CloseObjects
{
public:
    CloseObjects() {}
    CloseObjects(EntityRange *r, QPointF p): range(r), coords(p) {}
    QString findCloseObjects() const;
private:
    EntityRange*    range;
    QPointF         coords;
};

Map , , , ( + ) .


QString CloseObjects::findCloseObjects() const
{
    QString result;
    QTextStream stream(&result);
    //     2   
    stream.setRealNumberNotation(QTextStream::FixedNotation);
    stream.setRealNumberPrecision(2);
    for(QVector::const_iterator it = range->start; it != range->end; ++it)
    {
        float len = qSqrt(qPow((it->getCoords().x() - coords.x()),2) + qPow((it->getCoords().y() - coords.y()),2));
        if(len <= 350)
        {
            stream << it->fullDescription() << "\n" << QVariant(it->getCoords().x()/100).toFloat() << " " << QVariant((15360 - it->getCoords().y())/100).toFloat() << "\n";
        }
    }
    return result;
}

. , , .
pull-request.


:


Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/338734/

:  

: [1] []
 

:
: 

: ( )

:

  URL