Reebox 发表于 2021-9-21 23:23

如何从exe或dll中提取离线列车时刻数据

本帖最后由 Reebox 于 2021-9-22 20:13 编辑

各位大佬好,我是城市规划专业博士生,因论文需要,寻求从小程序(J程序和S程序,见链接)中提取历史年度的离线列车时刻数据(车次,站点,时刻,里程等等)。自己之前未接触过计算机专业,利用论坛提供的工具尝试未果,请求大佬帮助!


1.早期的J(以06年为例)由一个exe和一个dll文件组成,dll文件是离线时刻数据。尝试使用peid打开skb.dll,提示不是有效的PE文件。尝试使用reflector等软件,提示“ DOS header does not contain 'MZ' signatur”。用exeinfo查看exe,提示“delphi,nopacked”
2.后期的J(以15年为例)仅有一个exe文件,skb.dll内含于exe里了,我使用resscope或者exescope可以在txt目录下看到skb,并提取出来(所以15年的J文件夹内的skb是我自己提取出来的,在resscope界面内可以看到非常像时刻表的数据结构)。
3.从S提取时刻数据似乎难度更大,但J自2015年起停止更新,后续年份只能用S。使用exescope看不到类似skb.dll的列车时刻数据,使用peid打开提示“C++”。使用exeinfo打开提示“C++。no packed”。

顺祝各位大佬中秋快乐!

链接:
https://pan.baidu.com/s/1SsHTxiNlkaDaLTlSCU7CBw
提取码:keky

243634473 发表于 2021-9-23 09:43

逆向了它安卓版本的,数据在资源文件里。
数据的具体是什么意思不太懂,你自己研究。
数据加载在 com.p026sm.datacenter 这个类

https://attach.52pojie.cn//forum/202109/23/094129p866nk4h62poch62.png?l

这个是我的测试代码

    public static ArrayList[] dataloader_binary(String filename, int[] types) {
      int i = 0;
      int sCount = types.length;
      int rLen = 0;
      ArrayList[] cols = new ArrayList;
      for (int i2 : types) {
            switch (i2) {
                case 0:
                  rLen += 2;
                  break;
                case 1:
                  rLen += 4;
                  break;
                case 2:
                  rLen++;
                  break;
                case 3:
                  rLen += 8;
                  break;
            }
      }
      try {
            InputStream in = getInpustStream(filename);
            BufferedInputStream bis = new BufferedInputStream(in);
            DataInputStream dis = new DataInputStream(bis);
            int loops = in.available() / rLen;
            while (i < sCount) {
                switch (types) {
                  case 0:
                        cols = new ArrayList(loops);
                        break;
                  case 1:
                        cols = new ArrayList(loops);
                        break;
                  case 2:
                        cols = new ArrayList(loops);
                        break;
                  case 3:
                        cols = new ArrayList(loops);
                        break;
                }
                i++;
            }
            for (int idx = 0; idx < loops; idx++) {
                for (int i3 = 0; i3 < sCount; i3++) {
                  try {
                        switch (types) {
                            case 0:
                              cols.add(Short.valueOf(dis.readShort()));
                              break;
                            case 1:
                              cols.add(Integer.valueOf(dis.readInt()));
                              break;
                            case 2:
                              cols.add(Byte.valueOf(dis.readByte()));
                              break;
                            case 3:
                              cols.add(Long.valueOf(dis.readLong()));
                              break;
                        }
                  } catch (Exception e) {
                  }
                }
            }
            dis.close();
            bis.close();
            in.close();
            for (int i4 = 0; i4 < sCount; i4++) {
                cols.trimToSize();
            }
      } catch (Exception e2) {
            System.out.println("readUTF Error:" + e2.toString());
      } finally {
      }
      return cols;
    }


    public static InputStream getInpustStream(String filename) throws IOException {
      return new FileInputStream( filename);
    }



    public static ArrayList<String> dataloader_line(InputStream in, int iniSize) throws Exception {
      ArrayList<String> Rtns = iniSize > 0 ? new ArrayList<>(iniSize) : new ArrayList<>();
      InputStreamReader inputstreamReader = new InputStreamReader(in, "UTF-8");
      BufferedReader br = new BufferedReader(inputstreamReader);
      while (br.ready()) {
            Rtns.add(br.readLine());
      }
      br.close();
      inputstreamReader.close();
      in.close();
      return Rtns;
    }

    public static List<byte[]> dataloader_binary_BlockRead(String str, int i) {
      Exception e;
      int rLen = i;
      List cols = null;
      try {
            InputStream in = getInpustStream(str);
            BufferedInputStream bufferedInputStream = new BufferedInputStream(in);
            int available = in.available() / rLen;
            Vector arrayList = new Vector(available);
            try {
                byte[] bArr = new byte;
                for (int i2 = 0; i2 < available; i2++) {
                  bArr = new byte;
                  bufferedInputStream.read(bArr);
                  arrayList.add(bArr);
                }
                bufferedInputStream.close();
                in.close();
                System.gc();
                return arrayList;
            } catch (Exception e2) {
                e = e2;
                cols = arrayList;
                try {
                  System.out.println("readUTF Error:" + e.toString());
                  return cols;
                } catch (Throwable th) {
                  Throwable th2 = th;
                  try {
                        throw th2;
                  } catch (Throwable throwable) {
                        throwable.printStackTrace();
                  }
                }
            } catch (Throwable th3) {
            }
      } catch (Exception e3) {
            e = e3;
            System.out.println("readUTF Error:" + e.toString());
            return cols;
      }
      return null;
    }

    public static void main(String args[]) throws Exception {
//      ArrayList[] arrayLists = FastJsonUtils.dataloader_binary("F:\\安卓逆向\\AndroidKiller_v1.3.1\\projects\\smlcskbv2019.08.20_downcc.com\\Project\\assets\\data\\cctksy.dat", new int[]{1});
//      for (ArrayList arrayList : arrayLists) {
//            System.out.println("arrayList = " + arrayList);
//      }
      ArrayList<String> strings = FastJsonUtils.dataloader_line(getInpustStream("F:\\安卓逆向\\AndroidKiller_v1.3.1\\projects\\smlcskbv2019.08.20_downcc.com\\Project\\assets\\data\\cc.idx"), 4500);
      List<byte[]> bytes = FastJsonUtils.dataloader_binary_BlockRead("F:\\安卓逆向\\AndroidKiller_v1.3.1\\projects\\smlcskbv2019.08.20_downcc.com\\Project\\assets\\data\\cc.dat", 62);
      for (int i = 0; i < bytes.size(); i++) {
            ByteBuffer btsBuffer = ByteBuffer.wrap(bytes.get(i));
            String TrainName = strings.get(i);
            short TrainDJ = btsBuffer.get();
            short TrainSF = btsBuffer.get();
            int TrainInCCTKSYs = btsBuffer.getInt();
            int TrainInCCTKSYe = btsBuffer.getInt();
            boolean TrainSFKT = btsBuffer.get() + -48 == 1;
            String TrainXW = String.format("%04d", new Object[]{Short.valueOf(btsBuffer.getShort())});
            int TrainBJ = btsBuffer.get() - 48;
            short TrainKXZQ = btsBuffer.get();
            int TrainKXGL = (short) btsBuffer.getInt();
            int TrainKSRQ = btsBuffer.getInt();
            int TrainJSRQ = btsBuffer.getInt();
            int noticeStart = btsBuffer.getInt();
            int noticeEnd = btsBuffer.getInt();
            String ddj = new StringBuilder(String.valueOf((char) btsBuffer.get())).append((char) btsBuffer.get()).append((char) btsBuffer.get()).toString();
            int hcStart = btsBuffer.getInt();
            int hcEnd = btsBuffer.getInt();
            int pjdmStart = btsBuffer.getInt();
            int pjdmEnd = btsBuffer.getInt();
            int caceStart = btsBuffer.getInt();
            int caceEnd = btsBuffer.getInt();
            int ID = i;
            System.out.println("TrainName = " + TrainName +" TrainSFKT:"+TrainSFKT +" TrainXW:" + TrainXW + " ddj:"+ddj + " caceStart:"+caceStart+" caceEnd:"+caceEnd);
      }


    }

ynboyinkm 发表于 2021-9-22 19:14

Reebox 发表于 2021-9-22 13:20
和我同专业的学者曾经委托计算机专业人士提取成功过,就是从那个skb.dll中拿的数据。但是因为数据保密问 ...

离线的呀...   那就好好研究这个dll文件吧,说不定是一个数据库改为扩展名为dll,如果真是写在软件中没有加壳也不难!                                                                                                                                                               

xxkz 发表于 2021-9-22 08:07

留个记号,学习一下大牛的解决方法。

蓦留 发表于 2021-9-22 08:25

这俩都不是数据库文件吧,软件在线获取的吧

xxkz 发表于 2021-9-22 08:29

蓦留 发表于 2021-9-22 08:25
这俩都不是数据库文件吧,软件在线获取的吧

有离线版本的比如路路通

ynboyinkm 发表于 2021-9-22 08:42

从可执行的exe和dll提取呀?还是会fidd拦截着手呢

243634473 发表于 2021-9-22 08:48

smsk 这个里面有个wap接口 直接抓

Reebox 发表于 2021-9-22 13:12

本帖最后由 Reebox 于 2021-9-22 13:13 编辑

蓦留 发表于 2021-9-22 08:25
这俩都不是数据库文件吧,软件在线获取的吧
软件都是离线版本,最早的版本,时刻表数据是直接在exe之外的skb.dll。后期版本把skb.dll整合进exe了。可以确定skb.dll的内容是离线的时刻表数据,数据量在几百kb到1m左右。

Reebox 发表于 2021-9-22 13:16

243634473 发表于 2021-9-22 08:48
smsk 这个里面有个wap接口 直接抓

抱歉,我不是计算机专业的,不太理解。wap接口指的是在线交互的接口么?smsk是离线程序,里面内嵌了当年的时刻表数据。我有2016-2021年各个离线版本。如果是在线抓数据,那么和12306一样只能抓当下的时刻表数据,无法做历史性分析。

Reebox 发表于 2021-9-22 13:20

ynboyinkm 发表于 2021-9-22 08:42
从可执行的exe和dll提取呀?还是会fidd拦截着手呢

和我同专业的学者曾经委托计算机专业人士提取成功过,就是从那个skb.dll中拿的数据。但是因为数据保密问题,没有提供给我。只是告诉我有这么条路子。fidd似乎是和联网相关的?这两个小程序都是离线运行的。断网后照样可以查时刻(当年的历史数据)。我有从2005-2021年各个版本的这两个小程序,就是为了获取历史数据的。
页: [1] 2
查看完整版本: 如何从exe或dll中提取离线列车时刻数据