如何从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 逆向了它安卓版本的,数据在资源文件里。
数据的具体是什么意思不太懂,你自己研究。
数据加载在 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);
}
} Reebox 发表于 2021-9-22 13:20
和我同专业的学者曾经委托计算机专业人士提取成功过,就是从那个skb.dll中拿的数据。但是因为数据保密问 ...
离线的呀... 那就好好研究这个dll文件吧,说不定是一个数据库改为扩展名为dll,如果真是写在软件中没有加壳也不难! 留个记号,学习一下大牛的解决方法。 这俩都不是数据库文件吧,软件在线获取的吧 蓦留 发表于 2021-9-22 08:25
这俩都不是数据库文件吧,软件在线获取的吧
有离线版本的比如路路通 从可执行的exe和dll提取呀?还是会fidd拦截着手呢 smsk 这个里面有个wap接口 直接抓 本帖最后由 Reebox 于 2021-9-22 13:13 编辑
蓦留 发表于 2021-9-22 08:25
这俩都不是数据库文件吧,软件在线获取的吧
软件都是离线版本,最早的版本,时刻表数据是直接在exe之外的skb.dll。后期版本把skb.dll整合进exe了。可以确定skb.dll的内容是离线的时刻表数据,数据量在几百kb到1m左右。 243634473 发表于 2021-9-22 08:48
smsk 这个里面有个wap接口 直接抓
抱歉,我不是计算机专业的,不太理解。wap接口指的是在线交互的接口么?smsk是离线程序,里面内嵌了当年的时刻表数据。我有2016-2021年各个离线版本。如果是在线抓数据,那么和12306一样只能抓当下的时刻表数据,无法做历史性分析。 ynboyinkm 发表于 2021-9-22 08:42
从可执行的exe和dll提取呀?还是会fidd拦截着手呢
和我同专业的学者曾经委托计算机专业人士提取成功过,就是从那个skb.dll中拿的数据。但是因为数据保密问题,没有提供给我。只是告诉我有这么条路子。fidd似乎是和联网相关的?这两个小程序都是离线运行的。断网后照样可以查时刻(当年的历史数据)。我有从2005-2021年各个版本的这两个小程序,就是为了获取历史数据的。
页:
[1]
2