使用 LD_PRELOAD 挂接到 Linux 可执行文件不起作用

Hooking into Linux executable with LD_PRELOAD not work

提问人:DungND 提问时间:10/22/2023 更新时间:10/22/2023 访问量:34

问:

我有旧游戏,我想修复这个游戏的核心转储。我使用 gdb 来恢复游戏类并创建我自己的共享库 .so 文件。 但是,当我使用 LD_PRELOAD 运行程序时,编码时没有任何变化。 该程序在 Linux 32 位上运行。

$ ldd ./jx_linux_y
        linux-gate.so.1 =>  (0xf77d0000)
        libdl.so.2 => /lib/libdl.so.2 (0xf77c4000)
        libuuid.so.1 => /lib/libuuid.so.1 (0xf77be000)
        libpthread.so.0 => /lib/libpthread.so.0 (0xf77a3000)
        libstdc++.so.6 => /lib/libstdc++.so.6 (0xf76b7000)
        libm.so.6 => /lib/libm.so.6 (0xf7674000)
        libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xf7659000)
        libc.so.6 => /lib/libc.so.6 (0xf748e000)
        /lib/ld-linux.so.2 (0xf77d1000)

请帮助我知道为什么。谢谢

我尝试编译自己的代码:

/usr/bin/gcc -lgcc_s -lstdc++ -m32 -ldl -std=c++11 -fPIC -共享游戏服务器.cpp -o gameserver.so

#include <stdio.h>
#include "KBuySell.h"

bool KBuySell::Init(void)
{
    printf("===========================\n");
    printf("Test hooking KBuySell::Init\n");
    printf("===========================\n");

    return 1;
};

bool KBuySell::Buy(int nPlayerIdx, int nBuy, int nBuyIdx, int nPlace, int nX, int nY)
{
    printf("===========================\n");
    printf("Test hooking KBuySell::Buy\n");
    printf("===========================\n");

    return 1;
};

KBuySell.h

#include <map>
#include "KSG_LogFile.h"
#include "KMemFile.h"

class KGoods;
class KItem;
class KTabFile;

enum CurrencyType
{
  CURRENCYTYPE_NONE,
  CURRENCYTYPE_MONEY,
  CURRENCYTYPE_FUYUAN,
  CURRENCYTYPE_COIN,
  CURRENCYTYPE_SCORE,
  CURRENCYTYPE_GOLDCOIN,
  CURRENCYTYPE_SLIVER,
  CURRENCYTYPE_TICKET,
  CURRENCYTYPE_YUANBAO,
  CURRENCYTYPE_GOLDCOIN_NEW,
  CURRENCYTYPE_CONTRIBUTION,
  CURRENCYTYPE_HONOUR,
  CURRENCYTYPE_GOLDCOIN_SCORE,
  CURRENCYTYPE_RESPECT,
  CURRENCYTYPE_REFINING,
  CURRENCYTYPE_ENERGY,
  CURRENCYTYPE_ARENA_CREDITS,
  CURRENCYTYPE_END
};

class KBuySell : public KMemFileNotifyHelper
{
  enum SALE_BEHAVIOR
  {
    BUY,
    SELL
  };

public:
  int **m_ShopGoods;

private:
  KGoods *m_Goods;
  int m_Width;
  int m_Height;
  int m_MaxGoods;
  static KTabFile ms_ItemBusinessShopSetting;
  std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char>>, int, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char>> const, int>>> m_mapGoodsName;
  KItem *m_arySaleLogItem;
  int m_nSaleLogItemCount;
  KSG_LogFile m_SaleLogFile;

public:
  KBuySell();
  ~KBuySell();
  bool Init(void);
  int GetWidth(void);
  int GetHeight(void);
  int GetGoodsCount(void);
  KGoods *GetGoods(int);
  KGoods *GetGoods(const char *);
  int GetGoodsIndex(int, int);
  bool BuyCallBack(int, int, int);
  int AddGoodsToPlayer(int, KGoods *, CurrencyType, int, long long, int, int, int);
  void OpenSale(int, int, CurrencyType, int, const char *);
  void OpenItemBussinessSale(int, int, CurrencyType, int, const char *);
  bool Buy(int, int, int, int, int, int);
  bool Sell(int, int, int);
  void CreateStores(int);
  void AddShop2Stores(int, int, const char *, CurrencyType, int, const char *, bool);
  void OpenStores(int);
  void StoresChangeShop(int, int);
  bool WriteLog(int, KItem *, int, CurrencyType, int, KBuySell::SALE_BEHAVIOR, bool);
  bool WriteLog(int, KGoods *, int, CurrencyType, int, KBuySell::SALE_BEHAVIOR, bool);
  bool WriteLog(int, char *);
  static int ItemBusinessShopName2ID(char *);
  bool OnNotifyGoldCoinChangeResult(int, int, int, bool);
  bool OnNotifyBuyItem(int, int, int, long long);
  void ExportGoodsInfo(void);

private:
  bool LoadDataFromFile(void);
  bool RemoveAllData(void);
  virtual bool OnFileChanged(const char *, unsigned long, unsigned long);
  virtual bool OnlyForFileListChanged(void);
  bool InitItemSaleLog(void);
};

KMemFile.h

class IKMemFileNotify {
  public:
    virtual bool OnFileChanged(const char *, unsigned long, unsigned long);
    virtual bool OnlyForFileListChanged(void);
};


class KMemFileNotifyHelper : public IKMemFileNotify {
  private:
    unsigned long m_dwFileListGUID;
    unsigned long m_dwVerifyCode;

  public:
    KMemFileNotifyHelper(unsigned long);
    ~KMemFileNotifyHelper();
    unsigned long GetMemFileListGUID(void);
    unsigned long GetMemFileVerifyCode(void);
    virtual bool OnFileChanged(const char *, unsigned long, unsigned long);
};

KSG_LogFile.h

#include <stdint.h>
#include <stdio.h>

enum KE_LOGLEVEL
{
  emLOGLEVEL_FATAL,
  emLOGLEVEL_ERROR,
  emLOGLEVEL_WARN,
  emLOGLEVEL_INFO,
  emLOGLEVEL_DEBUG
};

struct KSG_LogFile
{
private:
  static unsigned int s_uCurDayOfYear;
  FILE *m_pLog;
  unsigned int m_uDayOfYear;
  int m_bFileNameAutoChangeWithDate;
  char m_szFileNameKey[260];
  char m_szSuffixName[20];
  KE_LOGLEVEL m_nLevel;
  size_t m_nFileSize;
  char m_szFile[260];

public:
  KSG_LogFile(char const *);
  ~KSG_LogFile();
  int Init(char const *);
  int InitWithDate(char const *, char const *, int);
  void ChangeLogLevel(KE_LOGLEVEL);
  void printf(const char *, ...);
  void puts(const char *);
  void write_time(void);
  void write_date(void);
  void write_date_time(void);
  void write_date_time_in(long);
  void printf_t(char const *, ...);
  void puts_t(char const *);
  void log(KE_LOGLEVEL, char const *, ...);
  void log_t(KE_LOGLEVEL, char const *, ...);

private:
  void WriteLog(KE_LOGLEVEL, char const *, char *, int);
  void WriteLog(char const *, size_t);
  int OpenNewFile(void);
};

实际结果:在游戏中购买物品时,打印消息。

C++ Linux 子游戏引擎 ld-preload

评论

0赞 Sam Varshavchik 10/22/2023
这些符号是否在预加载的共享库中定义并在可执行文件中使用?这是行不通的。只有在某个共享库中定义并在可执行文件中引用的符号才能使用 trick 进行拦截。此外,即使这些是分离的符号,除非您的 C++ 编译器被确认与构建该“旧游戏”的任何编译器二进制 ABI 兼容,否则这只会将糟糕的情况变得更糟......LD_PRELOAD
0赞 DungND 10/22/2023
我试图反转并在此函数上添加断点,并确保定义了这些函数。

答: 暂无答案