主頁 >  其他 > 使用 shell 腳本自動申請進京證 (六環外) —— debug 程序

使用 shell 腳本自動申請進京證 (六環外) —— debug 程序

2023-05-10 08:07:30 其他

問題現象

用 shell 腳本寫了一個自動辦理六環外進京證的工具 《使用 shell 腳本自動申請進京證 (六環外)》,然而運行這個腳本總是回傳以下錯誤資訊:

{
  "msg": "目前辦理業務人數較多,請稍后再試,",
  "code": 500
}

咨詢 woodheader/jjz 專案的作者,了解到問題就是出在請求頭或引數上,仔細的檢查了傳入的各種引數,沒有發現任何問題;修改 http 頭的格式 (key 與 value 間增加空格),也沒有絲毫改善,

寫腳本花了兩天,除錯腳本花了三天卻還沒摸到門徑,真是見了鬼了,有時候懷疑是自己被拉進反作弊名單了,切換另外一臺設備的 source 和 authorization 后,結果還是出錯,真是離了大譜,

思路

目前在 android 設備的 App 上進行請求用同樣的引數是可以辦理成功的,并且有 VNET/Charles 的抓包資料,如果能對腳本的請求進行抓包,再將兩者對比起來看,問題就容易暴露了,

Charles 抓包 curl

Charles 抓包的教程網上比較多,這里就不贅述了,需要注意的是和 VNET 一樣,App 登錄階段不能抓包,否則登錄界面調不出來,

Charles 可以抓 App 的報文,如果也能抓腳本的報文,兩個一對比問題就水落石出啦~

經過一番百度,發現要讓 Charles 抓命令列的報文還比較麻煩,需要配置兩個環境變數:

export http_proxy=172.21.222.149:8888
export https_proxy=172.21.222.149:8888

其中 172.21.222.149:8888 就是 Charles 開啟代理的 IP 和埠:

然而開啟抓包后,curl 要么失敗,要么卡住,總是抓不到包:

> sh jinjing.sh 
check jq ok
check curl ok
check head ok
check cat ok
check awk ok
check grep ok
check date ok
state req: {"v":"3.4.1","sfzmhm":"150121198603226428","s-source":"bjjj-android","timestamp":"1677810190000"}
state headers:  -H Accept-Language:zh-CN,zh;q=0.8 -H User-Agent:okhttp-okgo/jeasonlzy -H source:8724a2428c3f47358741f978fd082810 -H authorization:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx -H Content-Type:application/json;charset=utf-8 -H Host:jjz.jtgl.beijing.gov.cn -H Connection:Keep-Alive -H Accept-Encoding:gzip -H Content-Length:0
jinjing.sh: line 99: [: too many arguments
query permits status ok: 
id [] from user token does not match given [150121198603226428], fatal error!

VNET 抓包 curl

Charles 不行就想到了 VNET,不過它只能在 android 設備上抓包,如何讓它抓 pc 上運行的 curl 呢?其實不難,把腳本放在設備上運行就好了,

adb shell 運行腳本

這個腳本只要有 shell 環境就能用,可移植性比較好,立馬用 adb shell 發送到設備上試試:

> adb push jinjing.sh /sdcard/
jinjing.sh: 1 file pushed, 0 skipped. 9.9 MB/s (11790 bytes in 0.001s)
> adb push config.ini /sdcard/
config.ini: 1 file pushed, 0 skipped. 0.2 MB/s (428 bytes in 0.002s)
> adb shell
PD1981:/ > cd /sdcard
PD1981:/sdcard > mkdir jjz
PD1981:/sdcard > mv jinjing.sh config.ini jjz/                                                                                                                                       
PD1981:/sdcard > cd jjz
PD1981:/sdcard/jjz > ls -lh 
total 16K
-rw-rw---- 1 root everybody 428 2023-02-10 16:01 config.ini
-rw-rw---- 1 root everybody 12K 2023-03-03 10:34 jinjing.sh
PD1981:/sdcard/jjz > sh jinjing.sh
jinjing.sh[1]:  #!: inaccessible or not found
please install jq before run this script, fatal error!

提示沒有檢測到 jq,這命令確實不是 android 標配,在 pc 上都需要安裝,更不要說這種移動設備了,

arm jq

翻開 jq 官網下載頁,各種預編譯版本中沒有 arm 平臺的:

通過包管理器直接安裝更是想都不要想,直接下載 linux 通用版本,無論是 32 位還是 64 位都不能執行:

> ./jq
/system/bin/sh: ./jq: not executable: 32-bit ELF file
> ./jq
/system/bin/sh: ./jq: not executable: 64-bit ELF file

網上搜索了一下,找到一個 aarch64 平臺的 rpm 包:jq-1.5-1.el7.aarch64.rpm

aarch64 應該就是 arm64 沒錯了,經過 cpio 解壓后得到了里面的 jq 可執行檔案:

> wget  https://download-ib01.fedoraproject.org/pub/epel/7/aarch64/Packages/j/jq-1.5-1.el7.aarch64.rpm
> rpm2cpio jq-1.5-1.el7.aarch64.rpm | cpio -div
./usr/bin/jq
./usr/lib64/libjq.so.1
./usr/lib64/libjq.so.1.0.4
./usr/share/doc/jq/AUTHORS
./usr/share/doc/jq/COPYING
./usr/share/doc/jq/README
./usr/share/doc/jq/README.md
./usr/share/man/man1/jq.1.gz
873 blocks

將 ./usr/bin/jq push 到設備執行,還是不行:

PD1981:/data/local/tmp/jjz > file jq
jq: ELF executable, 64-bit LSB arm64, dynamic (/lib/ld-linux-aarch64.so.1), BuildID=77ce7804044f5185df2d25650051ced0ea6bed94, stripped
PD1981:/data/local/tmp/jjz > ./jq --versoin
/system/bin/sh: ./jq: No such file or directory

這里還有一個小插曲,在默認的 /sdcard 目錄執行可執行檔案時失敗:

> ./jq
/system/bin/sh: ./jq: can't execute: Permission denied

即使給了 jq 可執行權限也不行 (chmod),經過一番百度,發現需要放在另一個目錄才可以:/data/local/tmp

交叉編譯 jq

好在 jq 是開源的,可以直接基于原始碼編譯,不過 android 設備上可沒有編譯環境,所以還得借助 linux 進行交叉編譯,

#! /bin/sh
git clone  https://github.com/stedolan/jq.git

cd jq
# git submodule update --init
# autoreconf will fail with following error:
# ...
# configure.ac:6: error: require Automake 1.14, but have 1.13.4
# autoreconf: automake failed with exit status: 1


mkdir build
cd build 

autoreconf -i ..
CPATH="${ANDROID_NDK_HOME}/toolchains/llvm/prebuilt/linux-x86_64/bin/"
../configure --without-oniguruma --disable-maintainer-mode  CFLAGS='-std=c99' --prefix=$PWD/install/ --host='armv7a-linux-androideabi21' CC="$CPATH/armv7a-linux-androideabi21-clang"  LD="$CPATH/arm-linux-androideabi-ld"  AR="$CPATH/arm-linux-androideabi-ar"

make
make install

參考網上的一篇文章改了改,用上面這個腳本可以編譯,前提是要有 android ndk 并將根目錄設定到環境變數 ANDROID_NDK_HOME,

另外有兩個小點需要注意:

  • 不要下載 jq 庫中的模塊 (submodule),否則 autoreconf 需要更高的版本,在我的環境中會報錯退出,下載模塊主要目的是為了編譯 oniguruma 正則匹配庫,而我們是忽略這個庫的,所以沒必要
  • 個人習慣創建臨時目錄 (build) 進行編譯,方便后期清理編譯產物,然而在 jq 這里卻遇到了麻煩,需要稍微做一點作業

第一個問題的報錯資訊:

> autoreconf -i .
libtoolize: putting auxiliary files in `.'.
libtoolize: copying file `./ltmain.sh'
libtoolize: putting macros in AC_CONFIG_MACRO_DIR, `m4'.
libtoolize: copying file `m4/libtool.m4'
libtoolize: copying file `m4/ltoptions.m4'
libtoolize: copying file `m4/ltsugar.m4'
libtoolize: copying file `m4/ltversion.m4'
libtoolize: copying file `m4/lt~obsolete.m4'
configure.ac:6: error: require Automake 1.14, but have 1.13.4
autoreconf: automake failed with exit status: 1

這里我的 automake 剛好是 1.13.4 < 1.14,如果你的機器上版本大于等于 1.14,隨便造,,

第二個問題的報錯資訊:

> make
...
  CC       src/lexer.lo
  YACC     src/parser.c
NOT building parser.c!
  CC       src/parser.lo
clang: error: no such file or directory: 'src/parser.c'
clang: error: no input files
make[2]: *** [src/parser.lo] Error 1
make[2]: Leaving directory `/home/users/yunhai01/test/jq/build'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/home/users/yunhai01/test/jq/build'
make: *** [all] Error 2
make  install-recursive
make[1]: Entering directory `/home/users/yunhai01/test/jq/build'
make[2]: Entering directory `/home/users/yunhai01/test/jq/build'
  YACC     src/parser.c
NOT building parser.c!
  CC       src/parser.lo
clang: error: no such file or directory: 'src/parser.c'
clang: error: no input files
make[2]: *** [src/parser.lo] Error 1
make[2]: Leaving directory `/home/users/yunhai01/test/jq/build'
make[1]: *** [install-recursive] Error 1
make[1]: Leaving directory `/home/users/yunhai01/test/jq/build'
make: *** [install] Error 2

這里報 src/parser.c 找不到,然而在上一級目錄中對應的位置卻是有的,應該是 yacc 生成 .c 檔案時放在了上一級目錄,而使用 build 目錄后 make 沒有找到該檔案,手動復制一下即可:

> cp ../src/parser.c src/
> make
make  all-recursive
make[1]: Entering directory `/home/users/yunhai01/test/jq/build'
make[2]: Entering directory `/home/users/yunhai01/test/jq/build'
  CC       src/parser.lo
  CCLD     libjq.la
  CC       src/main.o
  CCLD     jq
make[2]: Leaving directory `/home/users/yunhai01/test/jq/build'
make[1]: Leaving directory `/home/users/yunhai01/test/jq/build'

應該是 jq 的一個小 bug,已提交 issue,

> file install/bin/jq
jq: ELF 32-bit LSB shared object, ARM, version 1 (SYSV), dynamically linked (uses shared libs), not stripped

> adb push install/bin/jq /data/local/tmp/jjz/
> adb shell
PD1981:/ > cd /data/local/tmp/jjz
PD1981:/data/local/tmp/jjz > chmod u+x jq
PD1981:/data/local/tmp/jjz > export PATH="$PATH:$PWD"
PD1981:/data/local/tmp/jjz > jq --version
jq-1.6-159-gcff5336-dirty

push 到設備就能用啦,這里為了腳本呼叫方便設定了 PATH 環境變數,斷開 adb 后就失效了,需要每次登錄都設定一下,

shell 陣列初始化

有了 jq 就可以繼續開開心心地跑腳本了,然而得到當頭一棒:

> sh jinjing.sh
check jq ok
check curl ok
check head ok
check cat ok
check awk ok
check grep ok
check date ok
jinjing.sh[71]: syntax error: unexpected '('

看看 71 行的內容:

    local stateheader=()

再普通不過的 shell 陣列初始化語法,看起來非 bash 的 shell 不認,只好把它改成更通用的形式:

    local stateheader

這絲毫不影響陣列的初始化,

硬編碼日期

繼續運行腳本,這回跑通了,然而申請結果不正確:

{
  "code": 500,
  "msg": "進京日期不能為空!",
  "data": null,
  "from": "v2"
}

再看設定的申請日期:

in effect from 2023-02-25 to 2023-03-03
date: bad date +1 days
new permit will start from

居然是空,原來是 adb shell 中的 date 不支持 "+1 days" 這種 unix date 語法:

PD1981:/data/local/tmp/jjz > date '+%Y-%m-%d' -d "+1 days"                                                                                                              
date: bad date +1 days
PD1981:/data/local/tmp/jjz > date -v+1d "+%Y-%m-%d"                                                                                                                 
date: Unknown option 'v+1d' (see "date --help")

mac date 那種 "-v+1d" 也不支持,看 adb date 的說明:

$ date --help
Toybox 0.8.4-android multicall binary: https://landley.net/toybox (see toybox --help)

usage: date [-u] [-I RES] [-r FILE] [-d DATE] [+DISPLAY_FORMAT] [-D SET_FORMAT] [SET]

Set/get the current date/time. With no SET shows the current date.

-d	Show DATE instead of current time (convert date format)
-D	+FORMAT for SET or -d (instead of MMDDhhmm[[CC]YY][.ss])
-I RES	ISO 8601 with RESolution d=date/h=hours/m=minutes/s=seconds/n=ns
-r	Use modification time of FILE instead of current date
-u	Use UTC instead of current timezone

Supported input formats:

MMDDhhmm[[CC]YY][.ss]     POSIX
@UNIXTIME[.FRACTION]      seconds since midnight 1970-01-01
YYYY-MM-DD [hh:mm[:ss]]   ISO 8601
hh:mm[:ss]                24-hour time today

All input formats can be followed by fractional seconds, and/or a UTC
offset such as -0800.

All input formats can be preceded by TZ="id" to set the input time zone
separately from the output time zone. Otherwise $TZ sets both.

+FORMAT specifies display format string using strftime(3) syntax:

%% literal %             %n newline              %t tab
%S seconds (00-60)       %M minute (00-59)       %m month (01-12)
%H hour (0-23)           %I hour (01-12)         %p AM/PM
%y short year (00-99)    %Y year                 %C century
%a short weekday name    %A weekday name         %u day of week (1-7, 1=mon)
%b short month name      %B month name           %Z timezone name
%j day of year (001-366) %d day of month (01-31) %e day of month ( 1-31)
%N nanosec (output only)

%U Week of year (0-53 start Sunday)   %W Week of year (0-53 start Monday)
%V Week of year (1-53 start Monday, week < 4 days not part of this year)

%F "%Y-%m-%d"   %R "%H:%M"        %T "%H:%M:%S"        %z  timezone (-0800)
%D "%m/%d/%y"   %r "%I:%M:%S %p"  %h "%b"              %:z timezone (-08:00)
%x locale date  %X locale time    %c locale date/time  %s  unix epoch time

也沒看出來個所以然,搞不懂這個 adb date 了,好在只是除錯,可以直接硬編碼日期為一個合法值:

# mac date performs differs with other unix..
if [ ${IS_MAC} -eq 1 ]; then 
    issuedate=$(date "-v+${expire}d" '+%Y-%m-%d')
else 
    issuedate=$(date '+%Y-%m-%d' -d "+${expire} days")
fi

issuedate="2023-03-04"

然后就成功了!

{
  "code": 200,
  "msg": "資訊已提交,正在審核!",
  "data": [
    "溫馨提示",
    "1、請務必在進京之前,查看進京通行證是否審核通過;",
    "2、若審核未通過,請按提示資訊調整并重新申請;",
    "3、若審核通過,可在證件生效之前申請取消,每位注冊用戶每天僅有1次取消機會;",
    "4、在進京通行證未生效的情況下,外埠機動車禁止在限行區域內行駛;"
  ],
  "from": "v2"
}

VNET

本來要抓出錯的報文進行對比,沒想到 adb shell 上居然歪打正著跑通了,這下 VNET 抓包也沒什么用了,雖然通過指定 shell 可以實作抓包:

可以看到,http 頭中的 Key 名稱重復了,應該是 VNET 顯示的問題,另外對比 Charles 與 VNET 的抓包結果,發現以下欄位是 VNET 自己加的:

  • ip: 203.34.106.199
  • type: POST
  • time: 2023-03-03 15:48:51
  • size: 705
  • code: 200

可能是為了顯示方便,在腳本里加這些引數純粹是畫蛇添足,所以我都刪掉了,

這里有一個小插曲,如果不打開 curl 的 -k 引數,VNET 抓包會導致 curl 請求卡死,且 VNET 也抓不到包,這是通過 -v 選項發現的:

curl: (60) SSL certificate problem: self signed certificate in certificate chain
More details here: https://curl.haxx.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.

升級 curl

走到這一步就很有意思了:pc 上 curl 失敗、android 上成功;pc 上能抓 App 包、抓不到 curl 包;android 上能抓兩者的包但是都成功沒有對比意義,

現在能直接對比的只有 pc 上的 curl 和 android 的上 curl,于是對比了一下兩者的版本:

macOS:
> curl -V
curl 7.64.1 (x86_64-apple-darwin20.0) libcurl/7.64.1 (SecureTransport) LibreSSL/2.8.3 zlib/1.2.11 nghttp2/1.41.0
Release-Date: 2019-03-27
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp 
Features: AsynchDNS GSS-API HTTP2 HTTPS-proxy IPv6 Kerberos Largefile libz MultiSSL NTLM NTLM_WB SPNEGO SSL UnixSockets

CentOS:
> curl -V
curl 7.29.0 (x86_64-redhat-linux-gnu) libcurl/7.29.0 NSS/3.53.1 zlib/1.2.7 libidn/1.28 libssh2/1.8.0
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp scp sftp smtp smtps telnet tftp 
Features: AsynchDNS GSS-Negotiate IDN IPv6 Largefile NTLM NTLM_WB SSL libz unix-sockets 

android:
> curl -V
curl 7.73.0 (Android) libcurl/7.73.0 BoringSSL zlib/1.2.11
Release-Date: 2020-10-14
Protocols: file http https mqtt 
Features: AsynchDNS HTTPS-proxy IPv6 libz NTLM SSL UnixSockets

其實是三者,pc 有兩個:一個 linux,一個 mac,發現它們版本都不盡相同,不過 android 上的版本比 pc 的都大,可以考慮升級 linux 的版本到 7.87 嘗試,

這里沒有再用原始碼編譯安裝的方式,直接下載一個 linux x86 版本完事:

> bin/curl -V
curl 7.87.0 (x86_64-pc-linux-muslx32) libcurl/7.87.0 OpenSSL/1.1.1s zlib/1.2.12 libssh2/1.9.0 nghttp2/1.43.0
Release-Date: 2022-12-21
Protocols: dict file ftp ftps gopher gophers http https imap imaps mqtt pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: alt-svc AsynchDNS HSTS HTTP2 HTTPS-proxy IPv6 Largefile libz NTLM NTLM_WB SSL threadsafe TLS-SRP UnixSockets
> pwd
/home/users/yunhai01/tools
> echo $PATH
/home/yunh/.BCloud/bin:/home/users/yunhai01/.local/bin:/home/users/yunhai01/bin:/home/users/yunhai01/tools/bin:/home/users/yunhai01/project/android-ndk-r20:/usr/lib64/qt-3.3/bin:/usr/local/bin:/usr/bin:/opt/bin:/home/opt/bin:/home/users/yunhai01/tools/node-v14.17.0-linux-x64/bin
> curl -V
curl 7.29.0 (x86_64-redhat-linux-gnu) libcurl/7.29.0 NSS/3.53.1 zlib/1.2.7 libidn/1.28 libssh2/1.8.0
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp scp sftp smtp smtps telnet tftp 
Features: AsynchDNS GSS-Negotiate IDN IPv6 Largefile NTLM NTLM_WB SSL libz unix-sockets 
> type curl
curl is hashed (/usr/bin/curl)
> whereis curl
curl: /usr/bin/curl /home/users/yunhai01/tools/bin/curl /usr/share/man/man1/curl.1.gz

這里有一個小插曲,即使我將新下載的 curl 所在的路徑 (tools/bin) 放在了 PATH 環境變數當中,訪問 curl 時仍是訪問系統自帶的那個,只得將腳本中所有 curl 通過指定全路徑的方式來切換為新版,

最后在 linux 上執行腳本仍失敗,

對比 curl 輸出

走到這兒我是真的郁悶了,既然不能抓包,那就對比 curl -v 輸出吧!索性腳本已經能在 android 上跑通了,有個可以對比的基準了:

過濾掉一些版本的差異,發現了最重要的區別:Content-Length,android 上的長度是 340,而 pc 上只有 304,長度不足會導致 post 資料被截斷,服務器回傳 500,這就說通了,

那為何相同的請求資料會得到不同的長度呢?先看看請求資料到底是多長:

> echo ${issue_req} 
{"dabh":"null","hphm":"津ADY1951","hpzl":"52","vId":"1479816562371952600","jjdq":"海淀區","jjlk":"00401","jjlkmc":"京藏高速","jjmd":"01","jjmdmc":"自駕旅游","jjrq":"2023-03-04","jjzzl":"02","jsrxm":"云海","jszh":"150121198603226428","sfzmhm":"150121198603226428","xxdz":"百度大廈","sqdzbdjd":116.307393,"sqdzbdwd":40.057771}
$ echo ${issue_req} | wc -c
     341
$ echo ${#issue_req}
304

果然是請求成功的 340,其中多了個 1 是結尾換行,而腳本中指定的 Content-Length 是通過 shell 字串長度獲取的 (${#issue_req}),這個在 pc 上果然是 304,

所以問題的根因就清楚了,是錯誤的將 shell 字串長度做為了資料長度,當資料內容中不包含漢字時,它倆是一致的,這也是為什么 stateList 可以請求成功的原因;而當資料中包含 utf-8 漢字后,一個漢字占用 3 個位元組,在 shell 字串中卻只統計了一次,所以導致長度偏小,

這正是 —— 踏破鐵鞋無覓處,得來全不費功夫啊!明明感覺只隔了一層窗戶紙,沒想到捅破它卻用盡了渾身的力氣,哈哈~

痛定思痛,不要使用 shell 字串長度作為資料長度就是這個 bug 的經驗教訓,

復盤

最后來復盤一下,為何 adb shell 中包含漢字的字串長度就能等于資料長度呢?下面做個小實驗:

> data='https://www.cnblogs.com/goodcitizen/archive/2023/05/09/{"dabh":"null" "hphm":"津ADY1951" "hpzl":"52" "vId":"1479816562371952600" "jjdq":"海淀區" "jjlk":"00401" "jjlkmc":"京藏高速" "jjmd":"01" "jjmdmc":"自駕旅游" "jjrq":"2023-03-04" "jjzzl":"02" "jsrxm":"云海" "jszh":"150121198603226428" "sfzmhm":"150121198603226428" "xxdz":"百度大廈" "sqdzbdjd":116.307393 "sqdzbdwd":40.057771}'
> echo "${data}"
{"dabh":"null" "hphm":"津ADY1951" "hpzl":"52" "vId":"1479816562371952600" "jjdq":"海淀區" "jjlk":"00401" "jjlkmc":"京藏高速" "jjmd":"01" "jjmdmc":"自駕旅游" "jjrq":"2023-03-04" "jjzzl":"02" "jsrxm":"云海" "jszh":"150121198603226428" "sfzmhm":"150121198603226428" "xxdz":"百度大廈" "sqdzbdjd":116.307393 "sqdzbdwd":40.057771}
> echo ${#data}
304

> cat test.sh
#! /bin/sh
data='https://www.cnblogs.com/goodcitizen/archive/2023/05/09/{"dabh":"null" "hphm":"津ADY1951" "hpzl":"52" "vId":"1479816562371952600" "jjdq":"海淀區" "jjlk":"00401" "jjlkmc":"京藏高速" "jjmd":"01" "jjmdmc":"自駕旅游" "jjrq":"2023-03-04" "jjzzl":"02" "jsrxm":"云海" "jszh":"150121198603226428" "sfzmhm":"150121198603226428" "xxdz":"百度大廈" "sqdzbdjd":116.307393 "sqdzbdwd":40.057771}'
echo ${#data}
echo "${data}" | wc -c 
> sh test.sh
340
341

發現兩個有趣的現象:

  • 直接將資料賦給 adb shell 變數時,長度是 304 短缺 (注意如果不將 data 用雙引號括住,json 資料的外花括號將缺失,不清楚為何)
  • 呼叫 shell 腳本賦值給 shell 變數時,長度為 340 正常,與 wc 的輸出僅差了一個換行,可以看作是一致的

adb shell 在互動執行和腳本執行時行為還不一樣,這真是離大譜,感興趣的讀者可以進一步探究,我是查不動了,,

結語

本文記錄了一個腳本不作業的排查程序,在嘗試抓包進行報文對比思路的引導下,分別探索了 Charles pc 抓 curl -> VNET android 抓 curl -> jq arm 交叉編譯 -> 去除 shell 陣列初始化 -> 去除 date +1 -> 升級 curl -> 對比 pc 和 android 上的 curl -v 輸出,最終定位到了問題根因:使用 shell 字串長度作為資料長度、在操作 utf-8 漢字資料時計算了錯誤的 Content-Length、從而引發了服務端回傳錯誤回應的程序,

bug 沒什么神奇的,甚至有點低級,說出來還有點不好意思,不過探索問題的程序就是這樣,不到最后一刻,永遠不知道自己被多么小的錯誤絆倒了,雖然錯誤低級,排查的程序還是蠻高大上的,總體思路也是正確的,只是在具體的摸索程序中走了不少彎路,回頭來看看,也蠻有意思,特別是 android adb shell,真的對它產生了新的認知,

adb shell 拓展了 shell 腳本運行的平臺,之前寫的好多腳本,其實都可以稱到 android 設備上跑,這方面有一個 Termux 可用,如果再和定時執行聯系起來,大有可為,一機在手走遍天下,這樣看 linux 服務器都可以省了,哈哈~

后記

在寫這篇文章的時候,又對上述流程做了個梳理,補充兩個新的情況,

arm jq

正文使用的是 rpm 包,我在搜索時又找到一個 deb 包:jq_1.6-1ubuntu0.20.04.1_arm64.deb

> wget  http://ports.ubuntu.com/pool/universe/j/jq/jq_1.6-1ubuntu0.20.04.1_arm64.deb
> ar -vx jq_1.6-1ubuntu0.20.04.1_arm64.deb 
x - debian-binary
x - control.tar.xz
x - data.tar.xz
> tar xvf data.tar.xz
x ./
x ./usr/
x ./usr/bin/
x ./usr/bin/jq
x ./usr/share/
x ./usr/share/doc/
x ./usr/share/doc/jq/
x ./usr/share/doc/jq/AUTHORS.gz
x ./usr/share/doc/jq/copyright
x ./usr/share/man/
x ./usr/share/man/man1/
x ./usr/share/man/man1/jq.1.gz
x ./usr/share/doc/jq/README
x ./usr/share/doc/jq/changelog.Debian.gz

將它解壓并推送到設備上,還是沒效果,看來還必需走交叉編譯這步了,

Charles 抓包 curl

設定 http_proxy/https_proxy 環境變數后,啟動腳本,Charles 抓到 curl 的包了:

curl 也正常回傳了,之前卡死或失敗的場景不再復現了,神奇,

如果當時這一步走通的話,就可以直接對比 curl 的報文與 App 的報文找到原因了!而不用繞這么大一圈,Charles 坑我~

后來回想一下,可能是為 curl 增加了 -k 選項的緣故,

參考

[1]. Linux bash終端設定代理(proxy)訪問

[2]. Download jq

[3]. rpm檔案解壓

[4]. .deb檔案的解壓與壓縮

[5]. how-to-set-executable-permissions-on-a-file-in-android-to-execute-using-runtime

[6]. jq的交叉編譯

[7]. Shell curl 命令報錯:(60) SSL certificate problem: self signed certificate

[8]. curl download

[9]. Linux shell統計位元組數、字數、行數

本文來自博客園,作者:goodcitizen,轉載請注明原文鏈接:https://www.cnblogs.com/goodcitizen/p/debugging_500_problem_for_shell_script_of_enter_permits_of_beijing_sixth_ring.html

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/552012.html

標籤:其他

上一篇:2步打通ModelArts和Astro,實作AI應用快速落地

下一篇:返回列表

標籤雲
其他(158719) Python(38124) JavaScript(25407) Java(18024) C(15222) 區塊鏈(8263) C#(7972) AI(7469) 爪哇(7425) MySQL(7172) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5871) 数组(5741) R(5409) Linux(5336) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4570) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2432) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1965) Web開發(1951) HtmlCss(1932) python-3.x(1918) 弹簧靴(1913) C++(1912) xml(1889) PostgreSQL(1875) .NETCore(1857) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 使用 shell 腳本自動申請進京證 (六環外) —— debug 程序

    寫好的自動辦理六環外進京證腳本跑不通,總是回傳辦理業務人數較多 (500) 錯誤,Charles / VNET 抓包、android 交叉編譯 jq、升級 curl…都不起作用,最侄訓是神奇的 adb shell 幫了大忙,最后定位到根因,居然是用 shell 字串長度作為資料長度導致的,這錯誤犯... ......

    uj5u.com 2023-05-10 08:07:30 more
  • 2步打通ModelArts和Astro,實作AI應用快速落地

    摘要:本文以 ModelArts 的“找云寶”自動學習 AI 應用為例,結合低代碼平臺 Astro 輕應用快速實作一個“找云寶”小應用。 本文分享自華為云社區《【我與ModelArts的故事】2步打通 ModelArts 和 Astro 實作 AI 應用落地》,作者:胡琦。 引言 隨著 GPT 火爆 ......

    uj5u.com 2023-05-10 08:06:40 more
  • 【三維CAD軟體】上海道寧為您帶來國際一流的國產自主可控的三維C

    天工CAD?融合了新迪數字收購的國際一流三維CAD軟體技術和十幾年CAD軟體研發積累,是一款國產自主可控的三維CAD軟體,產品成熟度和技術能力比肩國際先進水平滿足工業企業研發設計需求 ......

    uj5u.com 2023-05-10 08:06:26 more
  • 人人實作ChatGPT自由,手把手教你零擼部署自己聊天私服

    我們知道chat gpt最近非常的火爆,朋友圈啊,短視頻到處都是chat gpt身影。 但是網上看到各種教程資源,都是不是百分一百的免費,毫無保留教給你的,要么是賣賬號 要么是割韭菜的。其實沒有什么可以學習的,使用他也很簡單,付費學習這些真不值得, 大家不要再去看網上那些其亂七八糟的了,什么使用需要 ......

    uj5u.com 2023-05-10 08:06:05 more
  • Laf Assistant:云開發從未如此爽快!

    原文鏈接:https://forum.laf.run/d/67 工欲善其事,必先利其器。在撰寫代碼時,IDE 也是我們不可或缺的。它可以讓我們更高效地完成代碼撰寫,提高開發效率。因此,IDE 是我們撰寫代碼中最親密的伙伴之一。 雖然 Laf 云開發有簡潔的 Web IDE,只要能打開瀏覽器就可以隨處 ......

    uj5u.com 2023-05-10 08:05:35 more
  • 精準測驗之程序與實踐

    精準測驗的核心組件包含的軟體測驗示波器、用例和代碼的雙向追溯、智能回歸測驗用例選取、覆寫率分析、缺陷定位、測驗用例聚類分析、測驗用例自動生成系統,這些功能完整的構成了精準測驗技術體系。 ......

    uj5u.com 2023-05-10 08:03:32 more
  • 別玩手機 影像分類比賽

    如今,手機已成為大眾離不開的生活工具,而且它的迅速發展使得它的功能不再以通訊為主,手機逐漸發展為可移動的大眾傳播媒體終端設備,甚至可以比作為第五媒體。當今的大學生群體是智能手機使用者中的一支巨大的的隊伍,零零后大學生在進入大學以來,學習生活中過度的依賴手機,甚至上課時忘記攜帶手機便會手足無措,神情恍... ......

    uj5u.com 2023-05-10 08:02:20 more
  • 【AIGC】Embedding與LLM的結合:長文本搜索與問答功能

    什么是Embedding? Embedding是一種多維向量陣列,由一系列數字組成,可以代表任何事物,如文本、音樂、視頻等。在這里我們將重點關注文本部分。Embedding之所以重要,是因為它讓我們可以進行語意搜索,也就是通過文本的含義進行相似性檢索。 為什么Embedding在AI中如此重要? E ......

    uj5u.com 2023-05-10 08:02:12 more
  • 百度飛槳(PaddlePaddle)-數字識別

    手寫數字識別任務 用于對 0 ~ 9 的十類數字進行分類,即輸入手寫數字的圖片,可識別出這個圖片中的數字。 使用 pip 工具安裝 matplotlib 和 numpy python -m pip install matplotlib numpy -i https://mirror.baidu.co ......

    uj5u.com 2023-05-10 08:01:57 more
  • 2步打通ModelArts和Astro,實作AI應用快速落地

    摘要:本文以 ModelArts 的“找云寶”自動學習 AI 應用為例,結合低代碼平臺 Astro 輕應用快速實作一個“找云寶”小應用。 本文分享自華為云社區《【我與ModelArts的故事】2步打通 ModelArts 和 Astro 實作 AI 應用落地》,作者:胡琦。 引言 隨著 GPT 火爆 ......

    uj5u.com 2023-05-10 08:01:07 more