気軽に質問できるWebサービス「OSIETE」を作った
Amazon EC2のGPUインスタンスでハッシュ解読をやってみる
ハッシュ値から元の文字列を求めるハッシュ解読は、GPUを利用することにより高速に行えることが知られている。 ここでは、Amazon EC2のGPUインスタンスを利用し、oclHashcatを使った場合におけるハッシュ解読のパフォーマンスを調べてみる。
環境
- Amazon Linux AMI with NVIDIA GRID GPU Driver
- GPU instances、g2.2xlarge
US West (Oregon)リージョンの場合、かかる費用は$0.65/hr(1時間70円程度)である。 なお、GPUインスタンスを使うためにはインスタンス上限の制限緩和申請を行っておく必要がある。
oclHashcatでハッシュ解読をやってみる
oclHashcatは、GPUを使ってハッシュ値の解読を試みるアプリケーションである。
まず、EC2サーバにoclHashcatをダウンロードし、展開する。
$ sudo yum-config-manager --enable epel $ sudo yum install p7zip $ wget https://hashcat.net/files/cudaHashcat-2.01.7z $ 7za x cudaHashcat-2.01.7z $ cd cudaHashcat-2.01/
各種ハッシュ関数の解読速度を調べてみる。
$ ./cudaHashcat64.bin -b cudaHashcat v2.01 starting in benchmark-mode... Device #1: GRID K520, 4095MB, 797Mhz, 8MCU Hashtype: MD4 Workload: 1024 loops, 256 accel Speed.GPU.#1.: 3700.2 MH/s Hashtype: MD5 Workload: 1024 loops, 256 accel Speed.GPU.#1.: 2631.1 MH/s Hashtype: Half MD5 Workload: 1024 loops, 256 accel Speed.GPU.#1.: 777.2 MH/s Hashtype: SHA1 Workload: 1024 loops, 256 accel Speed.GPU.#1.: 697.0 MH/s Hashtype: SHA256 Workload: 1024 loops, 256 accel Speed.GPU.#1.: 286.6 MH/s Hashtype: SHA384 Workload: 256 loops, 256 accel Speed.GPU.#1.: 72515.6 kH/s Hashtype: SHA512 Workload: 256 loops, 256 accel Speed.GPU.#1.: 72445.1 kH/s Hashtype: SHA-3(Keccak) Workload: 128 loops, 256 accel Speed.GPU.#1.: 56513.4 kH/s Hashtype: SipHash Workload: 1024 loops, 256 accel Speed.GPU.#1.: 3269.6 MH/s Hashtype: RipeMD160 Workload: 1024 loops, 256 accel Speed.GPU.#1.: 522.4 MH/s Hashtype: Whirlpool Workload: 512 loops, 32 accel Speed.GPU.#1.: 43950.8 kH/s Hashtype: GOST R 34.11-94 Workload: 512 loops, 64 accel Speed.GPU.#1.: 41800.3 kH/s Hashtype: GOST R 34.11-2012 (Streebog) 256-bit Workload: 512 loops, 16 accel Speed.GPU.#1.: 9852.4 kH/s Hashtype: GOST R 34.11-2012 (Streebog) 512-bit Workload: 512 loops, 16 accel Speed.GPU.#1.: 9803.3 kH/s Hashtype: phpass, MD5(Wordpress), MD5(phpBB3), MD5(Joomla) Workload: 1024 loops, 32 accel Speed.GPU.#1.: 645.2 kH/s Hashtype: scrypt Workload: 1 loops, 64 accel Speed.GPU.#1.: 25092 H/s Hashtype: PBKDF2-HMAC-MD5 Workload: 1000 loops, 8 accel Speed.GPU.#1.: 702.0 kH/s Hashtype: PBKDF2-HMAC-SHA1 Workload: 1000 loops, 8 accel Speed.GPU.#1.: 330.0 kH/s Hashtype: PBKDF2-HMAC-SHA256 Workload: 1000 loops, 8 accel Speed.GPU.#1.: 114.8 kH/s Hashtype: PBKDF2-HMAC-SHA512 Workload: 1000 loops, 8 accel Speed.GPU.#1.: 31925 H/s Hashtype: Skype Workload: 1024 loops, 256 accel Speed.GPU.#1.: 779.3 MH/s Hashtype: WPA/WPA2 Workload: 1024 loops, 32 accel Speed.GPU.#1.: 41535 H/s Hashtype: IKE-PSK MD5 Workload: 512 loops, 128 accel Speed.GPU.#1.: 208.1 MH/s Hashtype: IKE-PSK SHA1 Workload: 512 loops, 128 accel Speed.GPU.#1.: 75893.2 kH/s Hashtype: NetNTLMv1-VANILLA / NetNTLMv1+ESS Workload: 1024 loops, 256 accel Speed.GPU.#1.: 1758.0 MH/s Hashtype: NetNTLMv2 Workload: 1024 loops, 32 accel Speed.GPU.#1.: 170.0 MH/s Hashtype: IPMI2 RAKP HMAC-SHA1 Workload: 256 loops, 256 accel Speed.GPU.#1.: 172.2 MH/s Hashtype: Kerberos 5 AS-REQ Pre-Auth etype 23 Workload: 256 loops, 32 accel Speed.GPU.#1.: 6255.5 kH/s Hashtype: DNSSEC (NSEC3) Workload: 512 loops, 256 accel Speed.GPU.#1.: 337.9 MH/s Hashtype: PostgreSQL Challenge-Response Authentication (MD5) Workload: 1024 loops, 256 accel Speed.GPU.#1.: 724.9 MH/s Hashtype: MySQL Challenge-Response Authentication (SHA1) Workload: 1024 loops, 256 accel Speed.GPU.#1.: 239.4 MH/s Hashtype: SIP digest authentication (MD5) Workload: 1024 loops, 32 accel Speed.GPU.#1.: 443.2 MH/s Hashtype: SMF > v1.1 Workload: 512 loops, 256 accel Speed.GPU.#1.: 275.1 MH/s Hashtype: vBulletin < v3.8.5 Workload: 1024 loops, 256 accel Speed.GPU.#1.: 713.8 MH/s Hashtype: vBulletin > v3.8.5 Workload: 1024 loops, 256 accel Speed.GPU.#1.: 515.0 MH/s Hashtype: IPB2+, MyBB1.2+ Workload: 1024 loops, 256 accel Speed.GPU.#1.: 526.3 MH/s Hashtype: WBB3, Woltlab Burning Board 3 Workload: 256 loops, 256 accel Speed.GPU.#1.: 137.4 MH/s Hashtype: Joomla < 2.5.18 Workload: 1024 loops, 256 accel Speed.GPU.#1.: 2631.4 MH/s Hashtype: PHPS Workload: 1024 loops, 256 accel Speed.GPU.#1.: 714.1 MH/s Hashtype: Drupal7 Workload: 1024 loops, 8 accel Speed.GPU.#1.: 4302 H/s Hashtype: osCommerce, xt:Commerce Workload: 1024 loops, 256 accel Speed.GPU.#1.: 779.3 MH/s Hashtype: PrestaShop Workload: 1024 loops, 256 accel Speed.GPU.#1.: 937.8 MH/s Hashtype: Django (SHA-1) Workload: 512 loops, 256 accel Speed.GPU.#1.: 273.1 MH/s Hashtype: Django (PBKDF2-SHA256) Workload: 1024 loops, 8 accel Speed.GPU.#1.: 5806 H/s Hashtype: Mediawiki B type Workload: 1024 loops, 256 accel Speed.GPU.#1.: 554.3 MH/s Hashtype: Redmine Project Management Web App Workload: 1024 loops, 256 accel Speed.GPU.#1.: 231.6 MH/s Hashtype: PostgreSQL Workload: 1024 loops, 256 accel Speed.GPU.#1.: 2632.8 MH/s Hashtype: MSSQL(2000) Workload: 512 loops, 256 accel Speed.GPU.#1.: 668.8 MH/s Hashtype: MSSQL(2005) Workload: 512 loops, 256 accel Speed.GPU.#1.: 668.6 MH/s Hashtype: MSSQL(2012) Workload: 256 loops, 256 accel Speed.GPU.#1.: 72135.6 kH/s Hashtype: MySQL323 Workload: 512 loops, 256 accel Speed.GPU.#1.: 8965.3 MH/s Hashtype: MySQL4.1/MySQL5 Workload: 512 loops, 256 accel Speed.GPU.#1.: 338.3 MH/s Hashtype: Oracle H: Type (Oracle 7+) Workload: 512 loops, 64 accel Speed.GPU.#1.: 115.2 MH/s Hashtype: Oracle S: Type (Oracle 11+) Workload: 1024 loops, 256 accel Speed.GPU.#1.: 696.8 MH/s Hashtype: Oracle T: Type (Oracle 12+) Workload: 1024 loops, 8 accel Speed.GPU.#1.: 7812 H/s Hashtype: Sybase ASE Workload: 512 loops, 32 accel Speed.GPU.#1.: 34292.9 kH/s Hashtype: EPiServer 6.x < v4 Workload: 512 loops, 256 accel Speed.GPU.#1.: 273.0 MH/s Hashtype: EPiServer 6.x > v4 Workload: 512 loops, 256 accel Speed.GPU.#1.: 268.2 MH/s Hashtype: md5apr1, MD5(APR), Apache MD5 Workload: 1000 loops, 32 accel Speed.GPU.#1.: 1173.5 kH/s Hashtype: ColdFusion 10+ Workload: 128 loops, 128 accel Speed.GPU.#1.: 188.8 MH/s Hashtype: hMailServer Workload: 512 loops, 256 accel Speed.GPU.#1.: 268.2 MH/s Hashtype: SHA-1(Base64), nsldap, Netscape LDAP SHA Workload: 1024 loops, 256 accel Speed.GPU.#1.: 697.1 MH/s Hashtype: SSHA-1(Base64), nsldaps, Netscape LDAP SSHA Workload: 1024 loops, 256 accel Speed.GPU.#1.: 696.7 MH/s Hashtype: SSHA-512(Base64), LDAP {SSHA512} Workload: 256 loops, 256 accel Speed.GPU.#1.: 72501.6 kH/s Hashtype: LM Workload: 1024 loops, 256 accel Speed.GPU.#1.: 483.0 MH/s Hashtype: NTLM Workload: 1024 loops, 256 accel Speed.GPU.#1.: 3616.9 MH/s Hashtype: Domain Cached Credentials (DCC), MS Cache Workload: 1024 loops, 256 accel Speed.GPU.#1.: 1204.0 MH/s Hashtype: Domain Cached Credentials 2 (DCC2), MS Cache 2 Workload: 1024 loops, 16 accel Speed.GPU.#1.: 33952 H/s Hashtype: MS-AzureSync PBKDF2-HMAC-SHA256 Workload: 100 loops, 256 accel Speed.GPU.#1.: 1202.3 kH/s Hashtype: descrypt, DES(Unix), Traditional DES Workload: 1024 loops, 64 accel Speed.GPU.#1.: 17319.2 kH/s Hashtype: BSDiCrypt, Extended DES Workload: 1024 loops, 256 accel Speed.GPU.#1.: 223.8 kH/s Hashtype: md5crypt, MD5(Unix), FreeBSD MD5, Cisco-IOS MD5 Workload: 1000 loops, 32 accel Speed.GPU.#1.: 1188.1 kH/s Hashtype: bcrypt, Blowfish(OpenBSD) Workload: 32 loops, 2 accel Speed.GPU.#1.: 509 H/s Hashtype: sha256crypt, SHA256(Unix) Workload: 1024 loops, 4 accel Speed.GPU.#1.: 44242 H/s Hashtype: sha512crypt, SHA512(Unix) Workload: 1024 loops, 8 accel Speed.GPU.#1.: 12919 H/s Hashtype: OSX v10.4, v10.5, v10.6 Workload: 512 loops, 256 accel Speed.GPU.#1.: 274.7 MH/s Hashtype: OSX v10.7 Workload: 128 loops, 256 accel Speed.GPU.#1.: 70910.0 kH/s Hashtype: OSX v10.8+ Workload: 1024 loops, 2 accel Speed.GPU.#1.: 824 H/s Hashtype: AIX {smd5} Workload: 1000 loops, 32 accel Speed.GPU.#1.: 1173.1 kH/s Hashtype: AIX {ssha1} Workload: 64 loops, 128 accel Speed.GPU.#1.: 4397.9 kH/s Hashtype: AIX {ssha256} Workload: 64 loops, 128 accel Speed.GPU.#1.: 1781.6 kH/s Hashtype: AIX {ssha512} Workload: 64 loops, 32 accel Speed.GPU.#1.: 483.2 kH/s Hashtype: Cisco-PIX MD5 Workload: 1024 loops, 256 accel Speed.GPU.#1.: 1792.4 MH/s Hashtype: Cisco-ASA MD5 Workload: 1024 loops, 256 accel Speed.GPU.#1.: 1876.0 MH/s Hashtype: Cisco-IOS SHA256 Workload: 1024 loops, 256 accel Speed.GPU.#1.: 286.5 MH/s Hashtype: Cisco $8$ Workload: 1024 loops, 8 accel Speed.GPU.#1.: 5807 H/s Hashtype: Cisco $9$ Workload: 1 loops, 4 accel Speed.GPU.#1.: 966 H/s Hashtype: Juniper Netscreen/SSG (ScreenOS) Workload: 1024 loops, 256 accel Speed.GPU.#1.: 779.6 MH/s Hashtype: Juniper IVE Workload: 1000 loops, 32 accel Speed.GPU.#1.: 1188.3 kH/s Hashtype: Android PIN Workload: 1024 loops, 16 accel Speed.GPU.#1.: 615.1 kH/s Hashtype: Citrix NetScaler Workload: 512 loops, 256 accel Speed.GPU.#1.: 754.8 MH/s Hashtype: RACF Workload: 1024 loops, 256 accel Speed.GPU.#1.: 260.5 MH/s Hashtype: GRUB 2 Workload: 1024 loops, 2 accel Speed.GPU.#1.: 2884 H/s Hashtype: Radmin2 Workload: 1024 loops, 256 accel Speed.GPU.#1.: 859.6 MH/s Hashtype: SAP CODVN B (BCODE) Workload: 1024 loops, 64 accel Speed.GPU.#1.: 219.6 MH/s Hashtype: SAP CODVN F/G (PASSCODE) Workload: 1024 loops, 32 accel Speed.GPU.#1.: 107.3 MH/s Hashtype: SAP CODVN H (PWDSALTEDHASH) iSSHA-1 Workload: 1024 loops, 16 accel Speed.GPU.#1.: 594.8 kH/s Hashtype: Lotus Notes/Domino 5 Workload: 256 loops, 32 accel Speed.GPU.#1.: 28342.8 kH/s Hashtype: Lotus Notes/Domino 6 Workload: 256 loops, 32 accel Speed.GPU.#1.: 9226.5 kH/s Hashtype: Lotus Notes/Domino 8 Workload: 1024 loops, 64 accel Speed.GPU.#1.: 72211 H/s Hashtype: PeopleSoft Workload: 512 loops, 256 accel Speed.GPU.#1.: 668.5 MH/s Hashtype: 7-Zip Workload: 1024 loops, 4 accel Speed.GPU.#1.: 1040 H/s Hashtype: RAR3-hp Workload: 16384 loops, 32 accel Speed.GPU.#1.: 7062 H/s Hashtype: TrueCrypt 5.0+ PBKDF2-HMAC-RipeMD160 + XTS 512 bit Workload: 1024 loops, 64 accel Speed.GPU.#1.: 31093 H/s Hashtype: TrueCrypt 5.0+ PBKDF2-HMAC-SHA512 + XTS 512 bit Workload: 1000 loops, 8 accel Speed.GPU.#1.: 30514 H/s Hashtype: TrueCrypt 5.0+ PBKDF2-HMAC-Whirlpool + XTS 512 bit Workload: 1000 loops, 8 accel Speed.GPU.#1.: 6080 H/s Hashtype: TrueCrypt 5.0+ PBKDF2-HMAC-RipeMD160 + XTS 512 bit + boot-mode Workload: 1000 loops, 128 accel Speed.GPU.#1.: 59915 H/s Hashtype: Android FDE <= 4.3 Workload: 1024 loops, 32 accel Speed.GPU.#1.: 84545 H/s Hashtype: eCryptfs Workload: 1024 loops, 8 accel Speed.GPU.#1.: 1068 H/s Hashtype: MS Office <= 2003 MD5 + RC4, oldoffice$0, oldoffice$1 Workload: 1024 loops, 32 accel Speed.GPU.#1.: 6063.9 kH/s Hashtype: MS Office <= 2003 MD5 + RC4, collision-mode #1 Workload: 1024 loops, 32 accel Speed.GPU.#1.: 9726.9 kH/s Hashtype: MS Office <= 2003 SHA1 + RC4, oldoffice$3, oldoffice$4 Workload: 1024 loops, 32 accel Speed.GPU.#1.: 8639.1 kH/s Hashtype: MS Office <= 2003 SHA1 + RC4, collision-mode #1 Workload: 1024 loops, 32 accel Speed.GPU.#1.: 10105.9 kH/s Hashtype: Office 2007 Workload: 1024 loops, 32 accel Speed.GPU.#1.: 14160 H/s Hashtype: Office 2010 Workload: 1024 loops, 32 accel Speed.GPU.#1.: 7087 H/s Hashtype: Office 2013 Workload: 1024 loops, 4 accel Speed.GPU.#1.: 699 H/s Hashtype: PDF 1.1 - 1.3 (Acrobat 2 - 4) Workload: 1024 loops, 32 accel Speed.GPU.#1.: 9990.0 kH/s Hashtype: PDF 1.1 - 1.3 (Acrobat 2 - 4) + collider-mode #1 Workload: 1024 loops, 32 accel Speed.GPU.#1.: 11320.5 kH/s Hashtype: PDF 1.4 - 1.6 (Acrobat 5 - 8) Workload: 70 loops, 256 accel Speed.GPU.#1.: 469.1 kH/s Hashtype: PDF 1.7 Level 3 (Acrobat 9) Workload: 1024 loops, 256 accel Speed.GPU.#1.: 286.5 MH/s Hashtype: PDF 1.7 Level 8 (Acrobat 10 - 11) Workload: 64 loops, 8 accel Speed.GPU.#1.: 3984 H/s Hashtype: Password Safe v2 Workload: 1000 loops, 16 accel Speed.GPU.#1.: 10654 H/s Hashtype: Password Safe v3 Workload: 1024 loops, 16 accel Speed.GPU.#1.: 118.4 kH/s Hashtype: Lastpass Workload: 500 loops, 64 accel Speed.GPU.#1.: 249.4 kH/s Hashtype: 1Password, agilekeychain Workload: 1000 loops, 64 accel Speed.GPU.#1.: 357.1 kH/s Hashtype: 1Password, cloudkeychain Workload: 1024 loops, 2 accel Speed.GPU.#1.: 722 H/s Hashtype: Bitcoin/Litecoin wallet.dat Workload: 1024 loops, 2 accel Speed.GPU.#1.: 323 H/s Hashtype: Blockchain, My Wallet Workload: 10 loops, 256 accel Speed.GPU.#1.: 6941.5 kH/s Started: Thu May 19 13:06:59 2016 Stopped: Thu May 19 13:47:20 2016
上の結果から、単純なハッシュ関数であるMD5やSHA-1、SHA-256に比べ、鍵導出関数と呼ばれるPBKDF2やscrypt、bcryptの解読速度が著しく遅いことが確認できる。 また、Core i5のサーバで計測した下の結果と比べると、解読速度に100倍程度の違いがあることがわかる。
$ ./hashcat-cli64.bin -b Initializing hashcat v2.00 with 4 threads and 32mb segment-size... Device...........: Intel(R) Core(TM) i5-4200U CPU @ 1.60GHz Instruction set..: x86_64 Number of threads: 4 Hash type: MD4 Speed/sec: 33.06M words Hash type: MD5 Speed/sec: 28.22M words Hash type: SHA1 Speed/sec: 15.90M words Hash type: SHA256 Speed/sec: 8.01M words Hash type: SHA512 Speed/sec: 3.30M words Hash type: SHA-3(Keccak) Speed/sec: 3.38M words (snip)
試しに、password
という8文字の文字列のMD5ハッシュ値を用意する。
$ echo -n password | md5sum 5f4dcc3b5aa765d61d8327deb882cf99 - $ echo 5f4dcc3b5aa765d61d8327deb882cf99 >hash.txt
mask_attack [hashcat wiki]を参考に、英小文字と数字からなる8文字以下のMD5ハッシュ値についてブルートフォースを行うと次のようになる。
$ ./cudaHashcat64.bin -m 0 -a 3 -i hash.txt -1 ?l?d ?1?1?1?1?1?1?1?1 cudaHashcat v2.01 starting... Device #1: GRID K520, 4095MB, 797Mhz, 8MCU Hashes: 1 hashes; 1 unique digests, 1 unique salts Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates Applicable Optimizers: * Zero-Byte * Precompute-Init * Precompute-Merkle-Demgard * Meet-In-The-Middle * Early-Skip * Not-Salted * Not-Iterated * Single-Hash * Single-Salt * Brute-Force * Scalar-Mode * Raw-Hash Watchdog: Temperature abort trigger set to 90c Watchdog: Temperature retain trigger set to 80c Device #1: Kernel ./kernels/4318/m00000_a3.sm_30.64.cubin Device #1: Kernel ./kernels/4318/markov_le_v1.sm_30.64.cubin ATTENTION! The wordlist or mask you are using is too small. Therefore, oclHashcat is unable to utilize the full parallelization power of your GPU(s). The cracking speed will drop. Workaround: https://hashcat.net/wiki/doku.php?id=frequently_asked_questions#how_to_create_more_work_for_full_speed INFO: approaching final keyspace, workload adjusted Session.Name...: cudaHashcat Status.........: Running Input.Mode.....: Mask (?1) [1] Hash.Target....: 5f4dcc3b5aa765d61d8327deb882cf99 Hash.Type......: MD5 Time.Started...: 0 secs Time.Estimated.: 0 secs Speed.GPU.#1...: 0 H/s Recovered......: 0/1 (0.00%) Digests, 0/1 (0.00%) Salts Progress.......: 36/36 (100.00%) Rejected.......: 0/36 (0.00%) HWMon.GPU.#1...: 1% Util, 35c Temp, N/A Fan ATTENTION! The wordlist or mask you are using is too small. Therefore, oclHashcat is unable to utilize the full parallelization power of your GPU(s). The cracking speed will drop. Workaround: https://hashcat.net/wiki/doku.php?id=frequently_asked_questions#how_to_create_more_work_for_full_speed INFO: approaching final keyspace, workload adjusted Session.Name...: cudaHashcat Status.........: Running Input.Mode.....: Mask (?1?1) [2] Hash.Target....: 5f4dcc3b5aa765d61d8327deb882cf99 Hash.Type......: MD5 Time.Started...: 0 secs Time.Estimated.: 0 secs Speed.GPU.#1...: 4977 H/s Recovered......: 0/1 (0.00%) Digests, 0/1 (0.00%) Salts Progress.......: 1296/1296 (100.00%) Rejected.......: 0/1296 (0.00%) HWMon.GPU.#1...: 0% Util, 35c Temp, N/A Fan ATTENTION! The wordlist or mask you are using is too small. Therefore, oclHashcat is unable to utilize the full parallelization power of your GPU(s). The cracking speed will drop. Workaround: https://hashcat.net/wiki/doku.php?id=frequently_asked_questions#how_to_create_more_work_for_full_speed INFO: approaching final keyspace, workload adjusted Session.Name...: cudaHashcat Status.........: Running Input.Mode.....: Mask (?1?1?1) [3] Hash.Target....: 5f4dcc3b5aa765d61d8327deb882cf99 Hash.Type......: MD5 Time.Started...: 0 secs Time.Estimated.: 0 secs Speed.GPU.#1...: 170.7 kH/s Recovered......: 0/1 (0.00%) Digests, 0/1 (0.00%) Salts Progress.......: 46656/46656 (100.00%) Rejected.......: 0/46656 (0.00%) HWMon.GPU.#1...: 0% Util, 35c Temp, N/A Fan ATTENTION! The wordlist or mask you are using is too small. Therefore, oclHashcat is unable to utilize the full parallelization power of your GPU(s). The cracking speed will drop. Workaround: https://hashcat.net/wiki/doku.php?id=frequently_asked_questions#how_to_create_more_work_for_full_speed INFO: approaching final keyspace, workload adjusted Session.Name...: cudaHashcat Status.........: Running Input.Mode.....: Mask (?1?1?1?1) [4] Hash.Target....: 5f4dcc3b5aa765d61d8327deb882cf99 Hash.Type......: MD5 Time.Started...: 0 secs Time.Estimated.: 0 secs Speed.GPU.#1...: 6313.7 kH/s Recovered......: 0/1 (0.00%) Digests, 0/1 (0.00%) Salts Progress.......: 1679616/1679616 (100.00%) Rejected.......: 0/1679616 (0.00%) HWMon.GPU.#1...: 1% Util, 35c Temp, N/A Fan INFO: approaching final keyspace, workload adjusted Session.Name...: cudaHashcat Status.........: Running Input.Mode.....: Mask (?1?1?1?1?1) [5] Hash.Target....: 5f4dcc3b5aa765d61d8327deb882cf99 Hash.Type......: MD5 Time.Started...: 0 secs Time.Estimated.: 0 secs Speed.GPU.#1...: 188.1 MH/s Recovered......: 0/1 (0.00%) Digests, 0/1 (0.00%) Salts Progress.......: 60466176/60466176 (100.00%) Rejected.......: 0/60466176 (0.00%) HWMon.GPU.#1...: 0% Util, 37c Temp, N/A Fan INFO: approaching final keyspace, workload adjusted Session.Name...: cudaHashcat Status.........: Running Input.Mode.....: Mask (?1?1?1?1?1?1) [6] Hash.Target....: 5f4dcc3b5aa765d61d8327deb882cf99 Hash.Type......: MD5 Time.Started...: 0 secs Time.Estimated.: 0 secs Speed.GPU.#1...: 1916.5 MH/s Recovered......: 0/1 (0.00%) Digests, 0/1 (0.00%) Salts Progress.......: 2176782336/2176782336 (100.00%) Rejected.......: 0/2176782336 (0.00%) HWMon.GPU.#1...: 99% Util, 40c Temp, N/A Fan INFO: approaching final keyspace, workload adjusted Session.Name...: cudaHashcat Status.........: Running Input.Mode.....: Mask (?1?1?1?1?1?1?1) [7] Hash.Target....: 5f4dcc3b5aa765d61d8327deb882cf99 Hash.Type......: MD5 Time.Started...: Thu May 19 14:17:10 2016 (30 secs) Time.Estimated.: 0 secs Speed.GPU.#1...: 2555.6 MH/s Recovered......: 0/1 (0.00%) Digests, 0/1 (0.00%) Salts Progress.......: 78364164096/78364164096 (100.00%) Rejected.......: 0/78364164096 (0.00%) HWMon.GPU.#1...: 99% Util, 49c Temp, N/A Fan 5f4dcc3b5aa765d61d8327deb882cf99:password Session.Name...: cudaHashcat Status.........: Cracked Input.Mode.....: Mask (?1?1?1?1?1?1?1?1) [8] Hash.Target....: 5f4dcc3b5aa765d61d8327deb882cf99 Hash.Type......: MD5 Time.Started...: Thu May 19 14:17:10 2016 (1 min, 58 secs) Speed.GPU.#1...: 2593.9 MH/s Recovered......: 1/1 (100.00%) Digests, 1/1 (100.00%) Salts Progress.......: 306570067968/2821109907456 (10.87%) Rejected.......: 0/306570067968 (0.00%) Restore.Point..: 6553600/60466176 (10.84%) HWMon.GPU.#1...: 0% Util, 57c Temp, N/A Fan Started: Thu May 19 14:17:10 2016 Stopped: Thu May 19 14:19:43 2016
上の結果より、2分30秒程度でハッシュ解読に成功していることが確認できる。
ここで、英小文字、英大文字、数字、記号(?a
、94文字)で8文字以下のMD5ブルートフォースにかかる時間を推定すると、27日程度となる。
(94 + 94^2 + ... + 94^8) / (2631.1 * 1000000) = 94 * (1-94^8)/(1-94) / 2631100000 = 2341695.272914663 (secs) = 27.102954547623415 (days)
また、GPUが四つのg2.8xlargeインスタンスを使った場合、かかる時間は上記の4分の1程度となることが推定できる。
関連リンク
Pythonでネイティブコードを実行する
Pythonでネイティブコード(x86バイトコードなど)を実行する方法のメモ。
ctypesモジュールをインポートし、次のような関数を定義すればよい。
import ctypes def native_func(bytecode): libc = ctypes.CDLL('libc.so.6') libc.mmap.restype = ctypes.c_void_p buf = libc.mmap(None, len(bytecode), 7, 0x22, -1, 0) libc.memcpy(ctypes.c_void_p(buf), ctypes.c_char_p(bytecode), len(bytecode)) return ctypes.CFUNCTYPE(ctypes.c_void_p)(buf) rdrand = native_func('\x48\x0f\xc7\xf0\xc3') # rdrand rax; ret print hex(rdrand())
上のコードでは、例としてハードウェア乱数を生成するRDRAND命令を実行し、その結果を返す関数を定義している。
実際に実行すると、実行ごとにランダムな値が返っていることが確認できる。
$ python native_func.py 0xd8e5dd17b96e3b07L $ python native_func.py 0xdfbac12088c27055L
追記(2016-06-06)
上ではネイティブコードの例としてRDRAND命令を実行したが、単にセキュアな乱数が必要な場合はos.urandom()
を用いればよい。
# urandom.py import os import struct randvalue = struct.unpack('<Q', os.urandom(8))[0] print hex(randvalue)
$ python urandom.py 0xd67b1aeabffab050L $ python urandom.py 0x784919deb3fa692
さらに安全性を求める場合は/dev/random
を利用することになるが、このデバイスは十分なエントロピーが確保されるまでブロックされることに注意する必要がある。
関連リンク
区間ふるいで2^32未満の素数を列挙する
232未満の素数すべてを列挙するアルゴリズムについてのメモ。 ついでに、C++11、Go、Rustの比較もやってみる。
環境
Ubuntu 14.04.4 LTS 64bit版、g++ 4.8.4、Go 1.6.2、Rust 1.8.0
$ uname -a Linux vm-ubuntu64 3.19.0-25-generic #26~14.04.1-Ubuntu SMP Fri Jul 24 21:16:20 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux $ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 14.04.4 LTS Release: 14.04 Codename: trusty $ g++ --version g++ (Ubuntu 4.8.4-2ubuntu1~14.04.1) 4.8.4 $ go version go version go1.6.2 linux/amd64 $ rustc --version rustc 1.8.0 (db2939409 2016-04-11)
区間ふるいによる素数列挙
単に232未満の最大の素数を求めるだけであれば、232から逆順に試し割りなどの素数判定アルゴリズムを適用すればよい。 一方、232未満のすべての素数を求める場合、素数列挙アルゴリズムを用いる必要がある。
素数列挙アルゴリズムの代表的なものにエラトステネスのふるいがあるが、単純な方法では最初に求めたい区間のテーブルを確保する必要があるため、232のような大きな区間については適用が難しい。 このような場合は、区間ふるい(Segmented Sieve)を用いることにより効率的に素数を列挙することができる。
区間ふるいは次のようなアルゴリズムである。
- 求めたい区間
[M, N]
の最大値N
に対し、sqrt(N)
以下の素数Ps
をエラトステネスのふるいで列挙する [M, N]
の区間についてテーブルを確保し、Ps
の倍数となる数をふるいにかける[M, N]
の区間が大きい場合は、適度な大きさに分割してそれぞれふるいにかければよい
232の区間を216ごとに分割する例について、C++11でコードで書くと次のようになる。
// sieve.cpp #include <iostream> #include <cstdint> #include <bitset> #include <vector> using namespace std; int main() { bitset<1<<16> is_composite; vector<uint32_t> primes; uint32_t i, j, k; for (i=2; i<1<<8; i++) { if (is_composite[i]) { continue; } for (j=i*2; j<1<<16; j+=i) { is_composite[j] = 1; } } for (i=2; i<1<<16; i++) { if (!is_composite[i]) { cout << i << endl; primes.push_back(i); } } for (k=1; k<1<<16; k++) { is_composite.reset(); uint32_t offset = k * (1<<16); for (auto p : primes) { i = offset + (p - offset % p) % p; while (i - offset < 1<<16) { is_composite[i - offset] = 1; i += p; } } for (i=0; i<1<<16; i++) { if (!is_composite[i]) { cout << offset + i << endl; } } } return 0; }
比較の目的も兼ねて、GoおよびRustで同様のコードを書くと次のようになる。
// sieve.go package main import "fmt" func main() { var is_composite [1<<16]bool primes := []uint32{} for i := 2; i < 1<<8; i++ { if is_composite[i] { continue; } for j := i*2; j < 1<<16; j += i { is_composite[j] = true; } } for i := uint32(2); i < 1<<16; i++ { if !is_composite[i] { fmt.Println(i) primes = append(primes, i) } } for k := 1; k < 1<<16; k++ { for i := range is_composite { is_composite[i] = false } offset := uint32(k * (1<<16)) for _, p := range primes { j := offset + (p - offset % p) % p for j - offset < 1<<16 { is_composite[j - offset] = true j += p } } for i := uint32(0); i < 1<<16; i++ { if !is_composite[i] { fmt.Println(offset + i) } } } }
// sieve.rs fn main() { let mut is_composite = [false; 1<<16]; let mut primes = vec![]; for i in 2..1<<8 { if is_composite[i] { continue; } let mut j = i*2; while j < 1<<16 { is_composite[j] = true; j += i; } } for i in 2..1<<16 { if !is_composite[i] { println!("{}", i); primes.push(i); } } for k in 1..1<<16 { is_composite = [false; 1<<16]; let offset = k * (1<<16); for &p in primes.iter() { let mut i = offset + (p - offset % p) % p; while i - offset < 1<<16 { is_composite[i - offset] = true; i += p; } } for i in 0..1<<16 { if !is_composite[i] { println!("{}", offset + i); } } } }
コンパイルにかかる時間を調べてみる。
$ time g++ -O2 -std=c++11 sieve.cpp -o sieve_cpp real 0m0.341s user 0m0.316s sys 0m0.020s $ time go build -o sieve_go sieve.go real 0m0.434s user 0m0.552s sys 0m0.088s $ time rustc -O sieve.rs -o sieve_rs real 0m0.405s user 0m0.372s sys 0m0.032s
コンパイル時間には大きな差がないことがわかる。
次に、実行にかかる時間を調べてみる。
$ time ./sieve_cpp >sieve_cpp.log real 6m10.568s user 1m29.476s sys 4m18.960s $ time ./sieve_go >sieve_go.log real 7m4.716s user 2m19.144s sys 4m33.612s $ time ./sieve_rs >sieve_rs.log real 6m21.845s user 1m44.284s sys 4m14.080s
ここではディスクI/O含むカーネル処理の時間(sys)は重要でないため、userに注目する。 C++とRustには大きな差がないが、Goは1分ほど長く時間がかかっていることがわかる。
生成される実行ファイルのサイズを調べてみる。
$ ls -l sieve_* -rwxr-xr-x 1 user user 13812 May 6 07:48 sieve_cpp* -rw-r--r-- 1 user user 2178719347 May 6 07:30 sieve_cpp.log -rwxr-xr-x 1 user user 2292936 May 6 07:48 sieve_go* -rw-r--r-- 1 user user 2178719347 May 6 07:38 sieve_go.log -rwxr-xr-x 1 user user 586264 May 6 07:49 sieve_rs* -rw-r--r-- 1 user user 2178719347 May 6 07:47 sieve_rs.log
ランタイムライブラリを含まないC++が最も小さく、Rust、Goと続くことがわかる。 また、同一の出力結果が得られていることも確認できる。
出力結果の内容を確認してみる。
$ tail sieve_cpp.log 4294967029 4294967087 4294967111 4294967143 4294967161 4294967189 4294967197 4294967231 4294967279 4294967291 $ factor 4294967291 4294967291: 4294967291 $ python -c "print 1<<32" 4294967296
上の結果から、232未満の最大の素数が4294967291であることが確認できる。
参考:生成されるアセンブリコード
ここでは、main関数に相当する部分のみを抜き出す。
$ objdump -d sieve_cpp | c++filt | awk '/<main/,/^$/' 00000000004009e0 <main>: 4009e0: 41 57 push r15 4009e2: b9 00 04 00 00 mov ecx,0x400 4009e7: 31 c0 xor eax,eax 4009e9: 41 b8 03 00 00 00 mov r8d,0x3 4009ef: be 02 00 00 00 mov esi,0x2 4009f4: 41 56 push r14 4009f6: 41 55 push r13 4009f8: 41 54 push r12 4009fa: 55 push rbp 4009fb: 53 push rbx 4009fc: 48 81 ec 38 20 00 00 sub rsp,0x2038 400a03: 48 8d 6c 24 30 lea rbp,[rsp+0x30] 400a08: 48 c7 44 24 10 00 00 mov QWORD PTR [rsp+0x10],0x0 400a0f: 00 00 400a11: 48 c7 44 24 18 00 00 mov QWORD PTR [rsp+0x18],0x0 400a18: 00 00 400a1a: 48 c7 44 24 20 00 00 mov QWORD PTR [rsp+0x20],0x0 400a21: 00 00 400a23: c7 44 24 0c 02 00 00 mov DWORD PTR [rsp+0xc],0x2 400a2a: 00 400a2b: 48 89 ef mov rdi,rbp 400a2e: f3 48 ab rep stos QWORD PTR es:[rdi],rax 400a31: bf 01 00 00 00 mov edi,0x1 400a36: 48 89 fa mov rdx,rdi 400a39: 89 f1 mov ecx,esi 400a3b: 48 d3 e2 shl rdx,cl 400a3e: 48 85 c2 test rdx,rax 400a41: 75 1e jne 400a61 <main+0x81> 400a43: 8d 0c 36 lea ecx,[rsi+rsi*1] 400a46: 89 c8 mov eax,ecx 400a48: 48 89 fa mov rdx,rdi 400a4b: 48 d3 e2 shl rdx,cl 400a4e: 48 c1 e8 06 shr rax,0x6 400a52: 01 f1 add ecx,esi 400a54: 48 09 54 c4 30 or QWORD PTR [rsp+rax*8+0x30],rdx 400a59: 81 f9 ff ff 00 00 cmp ecx,0xffff 400a5f: 76 e5 jbe 400a46 <main+0x66> 400a61: 83 c6 01 add esi,0x1 400a64: 81 fe 00 01 00 00 cmp esi,0x100 400a6a: 89 74 24 0c mov DWORD PTR [rsp+0xc],esi 400a6e: 74 12 je 400a82 <main+0xa2> 400a70: 4c 89 c0 mov rax,r8 400a73: 49 83 c0 01 add r8,0x1 400a77: 48 c1 e8 06 shr rax,0x6 400a7b: 48 8b 44 c4 30 mov rax,QWORD PTR [rsp+rax*8+0x30] 400a80: eb b4 jmp 400a36 <main+0x56> 400a82: c7 44 24 0c 02 00 00 mov DWORD PTR [rsp+0xc],0x2 400a89: 00 400a8a: b9 02 00 00 00 mov ecx,0x2 400a8f: bb 01 00 00 00 mov ebx,0x1 400a94: eb 17 jmp 400aad <main+0xcd> 400a96: 8b 4c 24 0c mov ecx,DWORD PTR [rsp+0xc] 400a9a: 83 c1 01 add ecx,0x1 400a9d: 81 f9 ff ff 00 00 cmp ecx,0xffff 400aa3: 89 4c 24 0c mov DWORD PTR [rsp+0xc],ecx 400aa7: 0f 87 9b 00 00 00 ja 400b48 <main+0x168> 400aad: 89 ce mov esi,ecx 400aaf: 48 89 da mov rdx,rbx 400ab2: 48 89 f0 mov rax,rsi 400ab5: 48 d3 e2 shl rdx,cl 400ab8: 48 c1 e8 06 shr rax,0x6 400abc: 48 85 54 c4 30 test QWORD PTR [rsp+rax*8+0x30],rdx 400ac1: 75 d3 jne 400a96 <main+0xb6> 400ac3: bf a0 20 60 00 mov edi,0x6020a0 400ac8: e8 c3 fe ff ff call 400990 <std::basic_ostream<char, std::char_traits<char> >& std::basic_ostream<char, std::char_traits<char> >::_M_insert<unsigned long>(unsigned long)@plt> 400acd: 49 89 c5 mov r13,rax 400ad0: 48 8b 00 mov rax,QWORD PTR [rax] 400ad3: 48 8b 40 e8 mov rax,QWORD PTR [rax-0x18] 400ad7: 4d 8b a4 05 f0 00 00 mov r12,QWORD PTR [r13+rax*1+0xf0] 400ade: 00 400adf: 4d 85 e4 test r12,r12 400ae2: 0f 84 13 02 00 00 je 400cfb <main+0x31b> 400ae8: 41 80 7c 24 38 00 cmp BYTE PTR [r12+0x38],0x0 400aee: 0f 84 72 01 00 00 je 400c66 <main+0x286> 400af4: 41 0f b6 44 24 43 movzx eax,BYTE PTR [r12+0x43] 400afa: 0f be f0 movsx esi,al 400afd: 4c 89 ef mov rdi,r13 400b00: e8 cb fe ff ff call 4009d0 <std::basic_ostream<char, std::char_traits<char> >::put(char)@plt> 400b05: 48 89 c7 mov rdi,rax 400b08: e8 73 fe ff ff call 400980 <std::basic_ostream<char, std::char_traits<char> >::flush()@plt> 400b0d: 48 8b 44 24 18 mov rax,QWORD PTR [rsp+0x18] 400b12: 48 3b 44 24 20 cmp rax,QWORD PTR [rsp+0x20] 400b17: 0f 84 65 01 00 00 je 400c82 <main+0x2a2> 400b1d: 48 85 c0 test rax,rax 400b20: 8b 4c 24 0c mov ecx,DWORD PTR [rsp+0xc] 400b24: 74 06 je 400b2c <main+0x14c> 400b26: 89 08 mov DWORD PTR [rax],ecx 400b28: 8b 4c 24 0c mov ecx,DWORD PTR [rsp+0xc] 400b2c: 83 c1 01 add ecx,0x1 400b2f: 48 83 c0 04 add rax,0x4 400b33: 81 f9 ff ff 00 00 cmp ecx,0xffff 400b39: 48 89 44 24 18 mov QWORD PTR [rsp+0x18],rax 400b3e: 89 4c 24 0c mov DWORD PTR [rsp+0xc],ecx 400b42: 0f 86 65 ff ff ff jbe 400aad <main+0xcd> 400b48: bb 00 00 01 00 mov ebx,0x10000 400b4d: 45 31 e4 xor r12d,r12d 400b50: 4c 8b 4c 24 10 mov r9,QWORD PTR [rsp+0x10] 400b55: 4c 8b 54 24 18 mov r10,QWORD PTR [rsp+0x18] 400b5a: b9 00 04 00 00 mov ecx,0x400 400b5f: 48 89 ef mov rdi,rbp 400b62: 4c 89 e0 mov rax,r12 400b65: f3 48 ab rep stos QWORD PTR es:[rdi],rax 400b68: 4d 39 d1 cmp r9,r10 400b6b: 0f 84 76 01 00 00 je 400ce7 <main+0x307> 400b71: 41 b8 01 00 00 00 mov r8d,0x1 400b77: 66 0f 1f 84 00 00 00 nop WORD PTR [rax+rax*1+0x0] 400b7e: 00 00 400b80: 41 8b 39 mov edi,DWORD PTR [r9] 400b83: 31 d2 xor edx,edx 400b85: 89 d8 mov eax,ebx 400b87: f7 f7 div edi 400b89: 89 f8 mov eax,edi 400b8b: 29 d0 sub eax,edx 400b8d: 31 d2 xor edx,edx 400b8f: f7 f7 div edi 400b91: 89 d1 mov ecx,edx 400b93: 8d 14 1a lea edx,[rdx+rbx*1] 400b96: 81 f9 ff ff 00 00 cmp ecx,0xffff 400b9c: 89 54 24 0c mov DWORD PTR [rsp+0xc],edx 400ba0: 77 29 ja 400bcb <main+0x1eb> 400ba2: 66 0f 1f 44 00 00 nop WORD PTR [rax+rax*1+0x0] 400ba8: 01 fa add edx,edi 400baa: 4c 89 c0 mov rax,r8 400bad: 89 ce mov esi,ecx 400baf: 48 d3 e0 shl rax,cl 400bb2: 89 d1 mov ecx,edx 400bb4: 48 c1 ee 06 shr rsi,0x6 400bb8: 29 d9 sub ecx,ebx 400bba: 48 09 44 f4 30 or QWORD PTR [rsp+rsi*8+0x30],rax 400bbf: 89 54 24 0c mov DWORD PTR [rsp+0xc],edx 400bc3: 81 f9 ff ff 00 00 cmp ecx,0xffff 400bc9: 76 dd jbe 400ba8 <main+0x1c8> 400bcb: 49 83 c1 04 add r9,0x4 400bcf: 4d 39 ca cmp r10,r9 400bd2: 75 ac jne 400b80 <main+0x1a0> 400bd4: 48 8b 44 24 30 mov rax,QWORD PTR [rsp+0x30] 400bd9: c7 44 24 0c 00 00 00 mov DWORD PTR [rsp+0xc],0x0 400be0: 00 400be1: 31 c9 xor ecx,ecx 400be3: 41 bd 01 00 00 00 mov r13d,0x1 400be9: eb 27 jmp 400c12 <main+0x232> 400beb: 0f 1f 44 00 00 nop DWORD PTR [rax+rax*1+0x0] 400bf0: 8b 44 24 0c mov eax,DWORD PTR [rsp+0xc] 400bf4: 8d 48 01 lea ecx,[rax+0x1] 400bf7: 81 f9 ff ff 00 00 cmp ecx,0xffff 400bfd: 89 4c 24 0c mov DWORD PTR [rsp+0xc],ecx 400c01: 0f 87 b1 00 00 00 ja 400cb8 <main+0x2d8> 400c07: 89 c8 mov eax,ecx 400c09: 48 c1 e8 06 shr rax,0x6 400c0d: 48 8b 44 c4 30 mov rax,QWORD PTR [rsp+rax*8+0x30] 400c12: 4c 89 ea mov rdx,r13 400c15: 48 d3 e2 shl rdx,cl 400c18: 48 85 d0 test rax,rdx 400c1b: 75 d3 jne 400bf0 <main+0x210> 400c1d: 8d 34 19 lea esi,[rcx+rbx*1] 400c20: bf a0 20 60 00 mov edi,0x6020a0 400c25: e8 66 fd ff ff call 400990 <std::basic_ostream<char, std::char_traits<char> >& std::basic_ostream<char, std::char_traits<char> >::_M_insert<unsigned long>(unsigned long)@plt> 400c2a: 49 89 c7 mov r15,rax 400c2d: 48 8b 00 mov rax,QWORD PTR [rax] 400c30: 48 8b 40 e8 mov rax,QWORD PTR [rax-0x18] 400c34: 4d 8b b4 07 f0 00 00 mov r14,QWORD PTR [r15+rax*1+0xf0] 400c3b: 00 400c3c: 4d 85 f6 test r14,r14 400c3f: 0f 84 b1 00 00 00 je 400cf6 <main+0x316> 400c45: 41 80 7e 38 00 cmp BYTE PTR [r14+0x38],0x0 400c4a: 74 54 je 400ca0 <main+0x2c0> 400c4c: 41 0f b6 46 43 movzx eax,BYTE PTR [r14+0x43] 400c51: 0f be f0 movsx esi,al 400c54: 4c 89 ff mov rdi,r15 400c57: e8 74 fd ff ff call 4009d0 <std::basic_ostream<char, std::char_traits<char> >::put(char)@plt> 400c5c: 48 89 c7 mov rdi,rax 400c5f: e8 1c fd ff ff call 400980 <std::basic_ostream<char, std::char_traits<char> >::flush()@plt> 400c64: eb 8a jmp 400bf0 <main+0x210> 400c66: 4c 89 e7 mov rdi,r12 400c69: e8 b2 fc ff ff call 400920 <std::ctype<char>::_M_widen_init() const@plt> 400c6e: 49 8b 04 24 mov rax,QWORD PTR [r12] 400c72: be 0a 00 00 00 mov esi,0xa 400c77: 4c 89 e7 mov rdi,r12 400c7a: ff 50 30 call QWORD PTR [rax+0x30] 400c7d: e9 78 fe ff ff jmp 400afa <main+0x11a> 400c82: 48 8d 74 24 0c lea rsi,[rsp+0xc] 400c87: 48 8d 7c 24 10 lea rdi,[rsp+0x10] 400c8c: e8 9f 01 00 00 call 400e30 <void std::vector<unsigned int, std::allocator<unsigned int> >::_M_emplace_back_aux<unsigned int const&>(unsigned int const&)> 400c91: e9 00 fe ff ff jmp 400a96 <main+0xb6> 400c96: 66 2e 0f 1f 84 00 00 nop WORD PTR cs:[rax+rax*1+0x0] 400c9d: 00 00 00 400ca0: 4c 89 f7 mov rdi,r14 400ca3: e8 78 fc ff ff call 400920 <std::ctype<char>::_M_widen_init() const@plt> 400ca8: 49 8b 06 mov rax,QWORD PTR [r14] 400cab: be 0a 00 00 00 mov esi,0xa 400cb0: 4c 89 f7 mov rdi,r14 400cb3: ff 50 30 call QWORD PTR [rax+0x30] 400cb6: eb 99 jmp 400c51 <main+0x271> 400cb8: 81 c3 00 00 01 00 add ebx,0x10000 400cbe: 0f 85 8c fe ff ff jne 400b50 <main+0x170> 400cc4: 48 8b 7c 24 10 mov rdi,QWORD PTR [rsp+0x10] 400cc9: 48 85 ff test rdi,rdi 400ccc: 74 05 je 400cd3 <main+0x2f3> 400cce: e8 3d fc ff ff call 400910 <operator delete(void*)@plt> 400cd3: 48 81 c4 38 20 00 00 add rsp,0x2038 400cda: 31 c0 xor eax,eax 400cdc: 5b pop rbx 400cdd: 5d pop rbp 400cde: 41 5c pop r12 400ce0: 41 5d pop r13 400ce2: 41 5e pop r14 400ce4: 41 5f pop r15 400ce6: c3 ret 400ce7: c7 44 24 0c 00 00 00 mov DWORD PTR [rsp+0xc],0x0 400cee: 00 400cef: 31 c0 xor eax,eax 400cf1: e9 eb fe ff ff jmp 400be1 <main+0x201> 400cf6: e8 f5 fb ff ff call 4008f0 <std::__throw_bad_cast()@plt> 400cfb: e8 f0 fb ff ff call 4008f0 <std::__throw_bad_cast()@plt> 400d00: 48 8b 7c 24 10 mov rdi,QWORD PTR [rsp+0x10] 400d05: 48 89 c3 mov rbx,rax 400d08: 48 85 ff test rdi,rdi 400d0b: 74 05 je 400d12 <main+0x332> 400d0d: e8 fe fb ff ff call 400910 <operator delete(void*)@plt> 400d12: 48 89 df mov rdi,rbx 400d15: e8 a6 fc ff ff call 4009c0 <_Unwind_Resume@plt> 400d1a: 66 0f 1f 44 00 00 nop WORD PTR [rax+rax*1+0x0]
$ objdump -d sieve_go | c++filt | awk '/<main/,/^$/' 0000000000401000 <main.main>: 401000: 64 48 8b 0c 25 f8 ff mov rcx,QWORD PTR fs:0xfffffffffffffff8 401007: ff ff 401009: 48 8b 71 10 mov rsi,QWORD PTR [rcx+0x10] 40100d: 48 81 fe de fa ff ff cmp rsi,0xfffffffffffffade 401014: 0f 84 de 04 00 00 je 4014f8 <main.main+0x4f8> 40101a: 48 8d 84 24 d0 02 00 lea rax,[rsp+0x2d0] 401021: 00 401022: 48 29 f0 sub rax,rsi 401025: 48 3d 08 03 01 00 cmp rax,0x10308 40102b: 0f 86 c7 04 00 00 jbe 4014f8 <main.main+0x4f8> 401031: 48 81 ec b8 00 01 00 sub rsp,0x100b8 401038: 0f 57 c0 xorps xmm0,xmm0 40103b: 0f 11 84 24 58 00 01 movups XMMWORD PTR [rsp+0x10058],xmm0 401042: 00 401043: 0f 11 84 24 68 00 01 movups XMMWORD PTR [rsp+0x10068],xmm0 40104a: 00 40104b: 0f 11 84 24 78 00 01 movups XMMWORD PTR [rsp+0x10078],xmm0 401052: 00 401053: 48 8d 7c 24 58 lea rdi,[rsp+0x58] 401058: 31 c0 xor eax,eax 40105a: 48 c7 c1 00 20 00 00 mov rcx,0x2000 401061: f3 48 ab rep stos QWORD PTR es:[rdi],rax 401064: 31 db xor ebx,ebx 401066: 48 8d 5c 24 40 lea rbx,[rsp+0x40] 40106b: 48 83 fb 00 cmp rbx,0x0 40106f: 0f 84 7c 04 00 00 je 4014f1 <main.main+0x4f1> 401075: 48 c7 84 24 90 00 01 mov QWORD PTR [rsp+0x10090],0x0 40107c: 00 00 00 00 00 401081: 48 c7 84 24 98 00 01 mov QWORD PTR [rsp+0x10098],0x0 401088: 00 00 00 00 00 40108d: 48 89 9c 24 88 00 01 mov QWORD PTR [rsp+0x10088],rbx 401094: 00 401095: 48 c7 c1 02 00 00 00 mov rcx,0x2 40109c: 48 81 f9 00 01 00 00 cmp rcx,0x100 4010a3: 7d 2e jge 4010d3 <main.main+0xd3> 4010a5: 48 8d 5c 24 58 lea rbx,[rsp+0x58] 4010aa: 48 81 f9 00 00 01 00 cmp rcx,0x10000 4010b1: 0f 83 33 04 00 00 jae 4014ea <main.main+0x4ea> 4010b7: 48 8d 1c 0b lea rbx,[rbx+rcx*1] 4010bb: 0f b6 1b movzx ebx,BYTE PTR [rbx] 4010be: 80 fb 00 cmp bl,0x0 4010c1: 0f 84 f1 03 00 00 je 4014b8 <main.main+0x4b8> 4010c7: 48 ff c1 inc rcx 4010ca: 48 81 f9 00 01 00 00 cmp rcx,0x100 4010d1: 7c d2 jl 4010a5 <main.main+0xa5> 4010d3: ba 02 00 00 00 mov edx,0x2 4010d8: 81 fa 00 00 01 00 cmp edx,0x10000 4010de: 0f 83 3b 01 00 00 jae 40121f <main.main+0x21f> 4010e4: 48 8d 5c 24 58 lea rbx,[rsp+0x58] 4010e9: 8b ea mov ebp,edx 4010eb: 48 81 fd 00 00 01 00 cmp rbp,0x10000 4010f2: 0f 83 b9 03 00 00 jae 4014b1 <main.main+0x4b1> 4010f8: 48 8d 1c 2b lea rbx,[rbx+rbp*1] 4010fc: 0f b6 1b movzx ebx,BYTE PTR [rbx] 4010ff: 80 fb 00 cmp bl,0x0 401102: 0f 85 09 01 00 00 jne 401211 <main.main+0x211> 401108: 89 54 24 48 mov DWORD PTR [rsp+0x48],edx 40110c: 89 54 24 4c mov DWORD PTR [rsp+0x4c],edx 401110: 31 db xor ebx,ebx 401112: 48 89 9c 24 78 00 01 mov QWORD PTR [rsp+0x10078],rbx 401119: 00 40111a: 48 89 9c 24 80 00 01 mov QWORD PTR [rsp+0x10080],rbx 401121: 00 401122: 48 8d 9c 24 78 00 01 lea rbx,[rsp+0x10078] 401129: 00 40112a: 48 83 fb 00 cmp rbx,0x0 40112e: 0f 84 76 03 00 00 je 4014aa <main.main+0x4aa> 401134: 48 c7 84 24 a8 00 01 mov QWORD PTR [rsp+0x100a8],0x1 40113b: 00 01 00 00 00 401140: 48 c7 84 24 b0 00 01 mov QWORD PTR [rsp+0x100b0],0x1 401147: 00 01 00 00 00 40114c: 48 89 9c 24 a0 00 01 mov QWORD PTR [rsp+0x100a0],rbx 401153: 00 401154: 48 8d 1d e5 7e 0b 00 lea rbx,[rip+0xb7ee5] # 4b9040 <type.*+0xe040> 40115b: 48 89 1c 24 mov QWORD PTR [rsp],rbx 40115f: 48 8d 5c 24 4c lea rbx,[rsp+0x4c] 401164: 48 89 5c 24 08 mov QWORD PTR [rsp+0x8],rbx 401169: 48 c7 44 24 10 00 00 mov QWORD PTR [rsp+0x10],0x0 401170: 00 00 401172: e8 89 ac 00 00 call 40be00 <runtime.convT2E> 401177: 48 8b 4c 24 18 mov rcx,QWORD PTR [rsp+0x18] 40117c: 48 8b 44 24 20 mov rax,QWORD PTR [rsp+0x20] 401181: 48 8b 9c 24 a0 00 01 mov rbx,QWORD PTR [rsp+0x100a0] 401188: 00 401189: 48 89 8c 24 68 00 01 mov QWORD PTR [rsp+0x10068],rcx 401190: 00 401191: 48 89 0b mov QWORD PTR [rbx],rcx 401194: 48 89 84 24 70 00 01 mov QWORD PTR [rsp+0x10070],rax 40119b: 00 40119c: 80 3d 3d e9 19 00 00 cmp BYTE PTR [rip+0x19e93d],0x0 # 59fae0 <runtime.writeBarrier> 4011a3: 0f 85 ea 02 00 00 jne 401493 <main.main+0x493> 4011a9: 48 89 43 08 mov QWORD PTR [rbx+0x8],rax 4011ad: 48 8b 9c 24 a0 00 01 mov rbx,QWORD PTR [rsp+0x100a0] 4011b4: 00 4011b5: 48 89 1c 24 mov QWORD PTR [rsp],rbx 4011b9: 48 8b 9c 24 a8 00 01 mov rbx,QWORD PTR [rsp+0x100a8] 4011c0: 00 4011c1: 48 89 5c 24 08 mov QWORD PTR [rsp+0x8],rbx 4011c6: 48 8b 9c 24 b0 00 01 mov rbx,QWORD PTR [rsp+0x100b0] 4011cd: 00 4011ce: 48 89 5c 24 10 mov QWORD PTR [rsp+0x10],rbx 4011d3: e8 b8 98 05 00 call 45aa90 <fmt.Println> 4011d8: 8b 54 24 48 mov edx,DWORD PTR [rsp+0x48] 4011dc: 48 8b 8c 24 88 00 01 mov rcx,QWORD PTR [rsp+0x10088] 4011e3: 00 4011e4: 48 8b 9c 24 90 00 01 mov rbx,QWORD PTR [rsp+0x10090] 4011eb: 00 4011ec: 48 8b b4 24 98 00 01 mov rsi,QWORD PTR [rsp+0x10098] 4011f3: 00 4011f4: 48 89 d8 mov rax,rbx 4011f7: 48 ff c3 inc rbx 4011fa: 48 39 f3 cmp rbx,rsi 4011fd: 0f 87 36 02 00 00 ja 401439 <main.main+0x439> 401203: 48 89 9c 24 90 00 01 mov QWORD PTR [rsp+0x10090],rbx 40120a: 00 40120b: 48 8d 1c 81 lea rbx,[rcx+rax*4] 40120f: 89 13 mov DWORD PTR [rbx],edx 401211: ff c2 inc edx 401213: 81 fa 00 00 01 00 cmp edx,0x10000 401219: 0f 82 c5 fe ff ff jb 4010e4 <main.main+0xe4> 40121f: 48 c7 c0 01 00 00 00 mov rax,0x1 401226: 48 89 44 24 50 mov QWORD PTR [rsp+0x50],rax 40122b: 48 3d 00 00 01 00 cmp rax,0x10000 401231: 0f 8d d1 01 00 00 jge 401408 <main.main+0x408> 401237: 48 8d 5c 24 58 lea rbx,[rsp+0x58] 40123c: 48 c7 c0 00 00 01 00 mov rax,0x10000 401243: 48 89 1c 24 mov QWORD PTR [rsp],rbx 401247: 48 89 44 24 08 mov QWORD PTR [rsp+0x8],rax 40124c: e8 3f 4e 05 00 call 456090 <runtime.memclr> 401251: 48 8b 74 24 50 mov rsi,QWORD PTR [rsp+0x50] 401256: 48 c1 e6 10 shl rsi,0x10 40125a: 89 f6 mov esi,esi 40125c: 48 8b bc 24 88 00 01 mov rdi,QWORD PTR [rsp+0x10088] 401263: 00 401264: 4c 8b 8c 24 90 00 01 mov r9,QWORD PTR [rsp+0x10090] 40126b: 00 40126c: 48 8b 9c 24 98 00 01 mov rbx,QWORD PTR [rsp+0x10098] 401273: 00 401274: 45 31 c0 xor r8d,r8d 401277: 4d 39 c8 cmp r8,r9 40127a: 7d 59 jge 4012d5 <main.main+0x2d5> 40127c: 8b 0f mov ecx,DWORD PTR [rdi] 40127e: 89 f0 mov eax,esi 401280: 31 d2 xor edx,edx 401282: f7 f1 div ecx 401284: 89 c8 mov eax,ecx 401286: 29 d0 sub eax,edx 401288: 31 d2 xor edx,edx 40128a: f7 f1 div ecx 40128c: 89 d0 mov eax,edx 40128e: 01 f0 add eax,esi 401290: 89 c3 mov ebx,eax 401292: 29 f3 sub ebx,esi 401294: 81 fb 00 00 01 00 cmp ebx,0x10000 40129a: 73 2d jae 4012c9 <main.main+0x2c9> 40129c: 89 c2 mov edx,eax 40129e: 29 f2 sub edx,esi 4012a0: 48 8d 5c 24 58 lea rbx,[rsp+0x58] 4012a5: 8b ea mov ebp,edx 4012a7: 48 81 fd 00 00 01 00 cmp rbp,0x10000 4012ae: 0f 83 7e 01 00 00 jae 401432 <main.main+0x432> 4012b4: 48 8d 1c 2b lea rbx,[rbx+rbp*1] 4012b8: c6 03 01 mov BYTE PTR [rbx],0x1 4012bb: 01 c8 add eax,ecx 4012bd: 89 c3 mov ebx,eax 4012bf: 29 f3 sub ebx,esi 4012c1: 81 fb 00 00 01 00 cmp ebx,0x10000 4012c7: 72 d3 jb 40129c <main.main+0x29c> 4012c9: 48 83 c7 04 add rdi,0x4 4012cd: 49 ff c0 inc r8 4012d0: 4d 39 c8 cmp r8,r9 4012d3: 7c a7 jl 40127c <main.main+0x27c> 4012d5: 31 c0 xor eax,eax 4012d7: 3d 00 00 01 00 cmp eax,0x10000 4012dc: 0f 83 0d 01 00 00 jae 4013ef <main.main+0x3ef> 4012e2: 48 8d 5c 24 58 lea rbx,[rsp+0x58] 4012e7: 8b e8 mov ebp,eax 4012e9: 48 81 fd 00 00 01 00 cmp rbp,0x10000 4012f0: 0f 83 35 01 00 00 jae 40142b <main.main+0x42b> 4012f6: 48 8d 1c 2b lea rbx,[rbx+rbp*1] 4012fa: 0f b6 1b movzx ebx,BYTE PTR [rbx] 4012fd: 80 fb 00 cmp bl,0x0 401300: 0f 85 dc 00 00 00 jne 4013e2 <main.main+0x3e2> 401306: 89 f3 mov ebx,esi 401308: 89 74 24 40 mov DWORD PTR [rsp+0x40],esi 40130c: 89 44 24 44 mov DWORD PTR [rsp+0x44],eax 401310: 01 c3 add ebx,eax 401312: 89 5c 24 4c mov DWORD PTR [rsp+0x4c],ebx 401316: 31 db xor ebx,ebx 401318: 48 89 9c 24 58 00 01 mov QWORD PTR [rsp+0x10058],rbx 40131f: 00 401320: 48 89 9c 24 60 00 01 mov QWORD PTR [rsp+0x10060],rbx 401327: 00 401328: 48 8d 9c 24 58 00 01 lea rbx,[rsp+0x10058] 40132f: 00 401330: 48 83 fb 00 cmp rbx,0x0 401334: 0f 84 ea 00 00 00 je 401424 <main.main+0x424> 40133a: 48 c7 84 24 a8 00 01 mov QWORD PTR [rsp+0x100a8],0x1 401341: 00 01 00 00 00 401346: 48 c7 84 24 b0 00 01 mov QWORD PTR [rsp+0x100b0],0x1 40134d: 00 01 00 00 00 401352: 48 89 9c 24 a0 00 01 mov QWORD PTR [rsp+0x100a0],rbx 401359: 00 40135a: 48 8d 1d df 7c 0b 00 lea rbx,[rip+0xb7cdf] # 4b9040 <type.*+0xe040> 401361: 48 89 1c 24 mov QWORD PTR [rsp],rbx 401365: 48 8d 5c 24 4c lea rbx,[rsp+0x4c] 40136a: 48 89 5c 24 08 mov QWORD PTR [rsp+0x8],rbx 40136f: 48 c7 44 24 10 00 00 mov QWORD PTR [rsp+0x10],0x0 401376: 00 00 401378: e8 83 aa 00 00 call 40be00 <runtime.convT2E> 40137d: 48 8b 4c 24 18 mov rcx,QWORD PTR [rsp+0x18] 401382: 48 8b 44 24 20 mov rax,QWORD PTR [rsp+0x20] 401387: 48 8b 9c 24 a0 00 01 mov rbx,QWORD PTR [rsp+0x100a0] 40138e: 00 40138f: 48 89 8c 24 68 00 01 mov QWORD PTR [rsp+0x10068],rcx 401396: 00 401397: 48 89 0b mov QWORD PTR [rbx],rcx 40139a: 48 89 84 24 70 00 01 mov QWORD PTR [rsp+0x10070],rax 4013a1: 00 4013a2: 80 3d 37 e7 19 00 00 cmp BYTE PTR [rip+0x19e737],0x0 # 59fae0 <runtime.writeBarrier> 4013a9: 75 65 jne 401410 <main.main+0x410> 4013ab: 48 89 43 08 mov QWORD PTR [rbx+0x8],rax 4013af: 48 8b 9c 24 a0 00 01 mov rbx,QWORD PTR [rsp+0x100a0] 4013b6: 00 4013b7: 48 89 1c 24 mov QWORD PTR [rsp],rbx 4013bb: 48 8b 9c 24 a8 00 01 mov rbx,QWORD PTR [rsp+0x100a8] 4013c2: 00 4013c3: 48 89 5c 24 08 mov QWORD PTR [rsp+0x8],rbx 4013c8: 48 8b 9c 24 b0 00 01 mov rbx,QWORD PTR [rsp+0x100b0] 4013cf: 00 4013d0: 48 89 5c 24 10 mov QWORD PTR [rsp+0x10],rbx 4013d5: e8 b6 96 05 00 call 45aa90 <fmt.Println> 4013da: 8b 44 24 44 mov eax,DWORD PTR [rsp+0x44] 4013de: 8b 74 24 40 mov esi,DWORD PTR [rsp+0x40] 4013e2: ff c0 inc eax 4013e4: 3d 00 00 01 00 cmp eax,0x10000 4013e9: 0f 82 f3 fe ff ff jb 4012e2 <main.main+0x2e2> 4013ef: 48 8b 44 24 50 mov rax,QWORD PTR [rsp+0x50] 4013f4: 48 ff c0 inc rax 4013f7: 48 89 44 24 50 mov QWORD PTR [rsp+0x50],rax 4013fc: 48 3d 00 00 01 00 cmp rax,0x10000 401402: 0f 8c 2f fe ff ff jl 401237 <main.main+0x237> 401408: 48 81 c4 b8 00 01 00 add rsp,0x100b8 40140f: c3 ret 401410: 4c 8d 43 08 lea r8,[rbx+0x8] 401414: 4c 89 04 24 mov QWORD PTR [rsp],r8 401418: 48 89 44 24 08 mov QWORD PTR [rsp+0x8],rax 40141d: e8 de de 00 00 call 40f300 <runtime.writebarrierptr> 401422: eb 8b jmp 4013af <main.main+0x3af> 401424: 89 03 mov DWORD PTR [rbx],eax 401426: e9 0f ff ff ff jmp 40133a <main.main+0x33a> 40142b: e8 a0 53 02 00 call 4267d0 <runtime.panicindex> 401430: 0f 0b ud2 401432: e8 99 53 02 00 call 4267d0 <runtime.panicindex> 401437: 0f 0b ud2 401439: 48 8d 2d 00 31 0b 00 lea rbp,[rip+0xb3100] # 4b4540 <type.*+0x9540> 401440: 48 89 2c 24 mov QWORD PTR [rsp],rbp 401444: 48 89 4c 24 08 mov QWORD PTR [rsp+0x8],rcx 401449: 48 89 44 24 10 mov QWORD PTR [rsp+0x10],rax 40144e: 48 89 74 24 18 mov QWORD PTR [rsp+0x18],rsi 401453: 48 89 5c 24 20 mov QWORD PTR [rsp+0x20],rbx 401458: e8 e3 9b 03 00 call 43b040 <runtime.growslice> 40145d: 8b 54 24 48 mov edx,DWORD PTR [rsp+0x48] 401461: 48 8b 4c 24 28 mov rcx,QWORD PTR [rsp+0x28] 401466: 48 8b 5c 24 30 mov rbx,QWORD PTR [rsp+0x30] 40146b: 48 8b 6c 24 38 mov rbp,QWORD PTR [rsp+0x38] 401470: 48 89 d8 mov rax,rbx 401473: 48 ff c3 inc rbx 401476: 48 89 9c 24 90 00 01 mov QWORD PTR [rsp+0x10090],rbx 40147d: 00 40147e: 48 89 ac 24 98 00 01 mov QWORD PTR [rsp+0x10098],rbp 401485: 00 401486: 48 89 8c 24 88 00 01 mov QWORD PTR [rsp+0x10088],rcx 40148d: 00 40148e: e9 78 fd ff ff jmp 40120b <main.main+0x20b> 401493: 4c 8d 43 08 lea r8,[rbx+0x8] 401497: 4c 89 04 24 mov QWORD PTR [rsp],r8 40149b: 48 89 44 24 08 mov QWORD PTR [rsp+0x8],rax 4014a0: e8 5b de 00 00 call 40f300 <runtime.writebarrierptr> 4014a5: e9 03 fd ff ff jmp 4011ad <main.main+0x1ad> 4014aa: 89 03 mov DWORD PTR [rbx],eax 4014ac: e9 83 fc ff ff jmp 401134 <main.main+0x134> 4014b1: e8 1a 53 02 00 call 4267d0 <runtime.panicindex> 4014b6: 0f 0b ud2 4014b8: 48 89 c8 mov rax,rcx 4014bb: 48 d1 e0 shl rax,1 4014be: 48 3d 00 00 01 00 cmp rax,0x10000 4014c4: 0f 8d fd fb ff ff jge 4010c7 <main.main+0xc7> 4014ca: 48 8d 5c 24 58 lea rbx,[rsp+0x58] 4014cf: 48 3d 00 00 01 00 cmp rax,0x10000 4014d5: 73 0c jae 4014e3 <main.main+0x4e3> 4014d7: 48 8d 1c 03 lea rbx,[rbx+rax*1] 4014db: c6 03 01 mov BYTE PTR [rbx],0x1 4014de: 48 01 c8 add rax,rcx 4014e1: eb db jmp 4014be <main.main+0x4be> 4014e3: e8 e8 52 02 00 call 4267d0 <runtime.panicindex> 4014e8: 0f 0b ud2 4014ea: e8 e1 52 02 00 call 4267d0 <runtime.panicindex> 4014ef: 0f 0b ud2 4014f1: 89 03 mov DWORD PTR [rbx],eax 4014f3: e9 7d fb ff ff jmp 401075 <main.main+0x75> 4014f8: e8 03 21 05 00 call 453600 <runtime.morestack_noctxt> 4014fd: e9 fe fa ff ff jmp 401000 <main.main> 401502: cc int3 401503: cc int3 401504: cc int3 401505: cc int3 401506: cc int3 401507: cc int3 401508: cc int3 401509: cc int3 40150a: cc int3 40150b: cc int3 40150c: cc int3 40150d: cc int3 40150e: cc int3 40150f: cc int3
$ objdump -d sieve_rs | c++filt | awk '/<main/,/^$/' 0000000000004cb0 <main::h3a7d143d57a98e1aeaa>: 4cb0: 55 push rbp 4cb1: 41 57 push r15 4cb3: 41 56 push r14 4cb5: 41 55 push r13 4cb7: 41 54 push r12 4cb9: 53 push rbx 4cba: 48 81 ec c8 00 01 00 sub rsp,0x100c8 4cc1: 48 b8 1d 1d 1d 1d 1d movabs rax,0x1d1d1d1d1d1d1d1d 4cc8: 1d 1d 1d 4ccb: 48 89 44 24 20 mov QWORD PTR [rsp+0x20],rax 4cd0: 48 8d bc 24 c8 00 00 lea rdi,[rsp+0xc8] 4cd7: 00 4cd8: 31 f6 xor esi,esi 4cda: ba 00 00 01 00 mov edx,0x10000 4cdf: e8 8c fa ff ff call 4770 <memset@plt> 4ce4: 48 c7 84 24 b0 00 00 mov QWORD PTR [rsp+0xb0],0x1 4ceb: 00 01 00 00 00 4cf0: 0f 57 c0 xorps xmm0,xmm0 4cf3: 0f 11 84 24 b8 00 00 movups XMMWORD PTR [rsp+0xb8],xmm0 4cfa: 00 4cfb: b8 02 00 00 00 mov eax,0x2 4d00: 48 89 c1 mov rcx,rax 4d03: 48 83 c9 01 or rcx,0x1 4d07: 80 bc 04 c8 00 00 00 cmp BYTE PTR [rsp+rax*1+0xc8],0x0 4d0e: 00 4d0f: 75 23 jne 4d34 <main::h3a7d143d57a98e1aeaa+0x84> 4d11: 48 8d 14 00 lea rdx,[rax+rax*1] 4d15: 66 66 2e 0f 1f 84 00 data32 nop WORD PTR cs:[rax+rax*1+0x0] 4d1c: 00 00 00 00 4d20: c6 84 14 c8 00 00 00 mov BYTE PTR [rsp+rdx*1+0xc8],0x1 4d27: 01 4d28: 48 01 c2 add rdx,rax 4d2b: 48 81 fa 00 00 01 00 cmp rdx,0x10000 4d32: 72 ec jb 4d20 <main::h3a7d143d57a98e1aeaa+0x70> 4d34: 48 83 c0 02 add rax,0x2 4d38: 80 bc 0c c8 00 00 00 cmp BYTE PTR [rsp+rcx*1+0xc8],0x0 4d3f: 00 4d40: 75 22 jne 4d64 <main::h3a7d143d57a98e1aeaa+0xb4> 4d42: 48 8d 14 09 lea rdx,[rcx+rcx*1] 4d46: 66 2e 0f 1f 84 00 00 nop WORD PTR cs:[rax+rax*1+0x0] 4d4d: 00 00 00 4d50: c6 84 14 c8 00 00 00 mov BYTE PTR [rsp+rdx*1+0xc8],0x1 4d57: 01 4d58: 48 01 ca add rdx,rcx 4d5b: 48 81 fa 00 00 01 00 cmp rdx,0x10000 4d62: 72 ec jb 4d50 <main::h3a7d143d57a98e1aeaa+0xa0> 4d64: 48 3d 00 01 00 00 cmp rax,0x100 4d6a: 75 94 jne 4d00 <main::h3a7d143d57a98e1aeaa+0x50> 4d6c: bd 02 00 00 00 mov ebp,0x2 4d71: 45 31 e4 xor r12d,r12d 4d74: 41 bf 01 00 00 00 mov r15d,0x1 4d7a: 4c 8d 6c 24 68 lea r13,[rsp+0x68] 4d7f: 48 8d 5c 24 78 lea rbx,[rsp+0x78] 4d84: 66 66 66 2e 0f 1f 84 data32 data32 nop WORD PTR cs:[rax+rax*1+0x0] 4d8b: 00 00 00 00 00 4d90: 48 89 ac 24 a8 00 00 mov QWORD PTR [rsp+0xa8],rbp 4d97: 00 4d98: 80 bc 2c c8 00 00 00 cmp BYTE PTR [rsp+rbp*1+0xc8],0x0 4d9f: 00 4da0: 0f 85 a1 00 00 00 jne 4e47 <main::h3a7d143d57a98e1aeaa+0x197> 4da6: 48 8d 05 03 72 03 00 lea rax,[rip+0x37203] # 3bfb0 <fmt::num::usize.fmt..Display::fmt::h841af16830bb5f60kgW> 4dad: 48 89 44 24 70 mov QWORD PTR [rsp+0x70],rax 4db2: 48 8d 84 24 a8 00 00 lea rax,[rsp+0xa8] 4db9: 00 4dba: 48 89 44 24 68 mov QWORD PTR [rsp+0x68],rax 4dbf: 48 8d 05 d2 84 24 00 lea rax,[rip+0x2484d2] # 24d298 <ref4653> 4dc6: 48 89 44 24 78 mov QWORD PTR [rsp+0x78],rax 4dcb: 48 c7 84 24 80 00 00 mov QWORD PTR [rsp+0x80],0x2 4dd2: 00 02 00 00 00 4dd7: 48 8d 84 24 88 00 00 lea rax,[rsp+0x88] 4dde: 00 4ddf: 0f 57 c0 xorps xmm0,xmm0 4de2: 0f 11 00 movups XMMWORD PTR [rax],xmm0 4de5: 4c 89 ac 24 98 00 00 mov QWORD PTR [rsp+0x98],r13 4dec: 00 4ded: 48 c7 84 24 a0 00 00 mov QWORD PTR [rsp+0xa0],0x1 4df4: 00 01 00 00 00 4df9: 48 89 df mov rdi,rbx 4dfc: e8 5f 2f 00 00 call 7d60 <io::stdio::_print::h27ae99cc97e67314Erh> 4e01: 4c 8b b4 24 a8 00 00 mov r14,QWORD PTR [rsp+0xa8] 4e08: 00 4e09: 4c 3b a4 24 b8 00 00 cmp r12,QWORD PTR [rsp+0xb8] 4e10: 00 4e11: 75 1d jne 4e30 <main::h3a7d143d57a98e1aeaa+0x180> 4e13: 48 8d bc 24 b0 00 00 lea rdi,[rsp+0xb0] 4e1a: 00 4e1b: e8 20 02 00 00 call 5040 <raw_vec::RawVec$LT$T$GT$::double::h4876174689768493710> 4e20: 4c 8b bc 24 b0 00 00 mov r15,QWORD PTR [rsp+0xb0] 4e27: 00 4e28: 4c 8b a4 24 c0 00 00 mov r12,QWORD PTR [rsp+0xc0] 4e2f: 00 4e30: 4f 89 34 e7 mov QWORD PTR [r15+r12*8],r14 4e34: 4c 8b a4 24 c0 00 00 mov r12,QWORD PTR [rsp+0xc0] 4e3b: 00 4e3c: 49 ff c4 inc r12 4e3f: 4c 89 a4 24 c0 00 00 mov QWORD PTR [rsp+0xc0],r12 4e46: 00 4e47: 48 ff c5 inc rbp 4e4a: 48 81 fd 00 00 01 00 cmp rbp,0x10000 4e51: 0f 82 39 ff ff ff jb 4d90 <main::h3a7d143d57a98e1aeaa+0xe0> 4e57: 48 8b 8c 24 b0 00 00 mov rcx,QWORD PTR [rsp+0xb0] 4e5e: 00 4e5f: 48 89 4c 24 08 mov QWORD PTR [rsp+0x8],rcx 4e64: 4c 89 64 24 10 mov QWORD PTR [rsp+0x10],r12 4e69: 4e 8d 34 e1 lea r14,[rcx+r12*8] 4e6d: bb 01 00 00 00 mov ebx,0x1 4e72: 41 bd 00 00 01 00 mov r13d,0x10000 4e78: 4c 8d 64 24 38 lea r12,[rsp+0x38] 4e7d: 0f 1f 00 nop DWORD PTR [rax] 4e80: 48 8d 43 01 lea rax,[rbx+0x1] 4e84: 48 89 44 24 18 mov QWORD PTR [rsp+0x18],rax 4e89: 31 f6 xor esi,esi 4e8b: ba 00 00 01 00 mov edx,0x10000 4e90: 48 8d bc 24 c8 00 00 lea rdi,[rsp+0xc8] 4e97: 00 4e98: e8 d3 f8 ff ff call 4770 <memset@plt> 4e9d: 48 83 7c 24 10 00 cmp QWORD PTR [rsp+0x10],0x0 4ea3: 4c 89 ed mov rbp,r13 4ea6: 41 bf 00 00 00 00 mov r15d,0x0 4eac: 0f 84 7e 00 00 00 je 4f30 <main::h3a7d143d57a98e1aeaa+0x280> 4eb2: 48 c1 e3 10 shl rbx,0x10 4eb6: 48 8b 4c 24 08 mov rcx,QWORD PTR [rsp+0x8] 4ebb: 0f 1f 44 00 00 nop DWORD PTR [rax+rax*1+0x0] 4ec0: 48 8b 31 mov rsi,QWORD PTR [rcx] 4ec3: 48 85 f6 test rsi,rsi 4ec6: 74 43 je 4f0b <main::h3a7d143d57a98e1aeaa+0x25b> 4ec8: 48 83 c1 08 add rcx,0x8 4ecc: 31 d2 xor edx,edx 4ece: 48 89 d8 mov rax,rbx 4ed1: 48 f7 f6 div rsi 4ed4: 48 89 f0 mov rax,rsi 4ed7: 48 29 d0 sub rax,rdx 4eda: 31 d2 xor edx,edx 4edc: 48 f7 f6 div rsi 4edf: 48 81 fa ff ff 00 00 cmp rdx,0xffff 4ee6: 77 1c ja 4f04 <main::h3a7d143d57a98e1aeaa+0x254> 4ee8: 0f 1f 84 00 00 00 00 nop DWORD PTR [rax+rax*1+0x0] 4eef: 00 4ef0: c6 84 14 c8 00 00 00 mov BYTE PTR [rsp+rdx*1+0xc8],0x1 4ef7: 01 4ef8: 48 01 f2 add rdx,rsi 4efb: 48 81 fa 00 00 01 00 cmp rdx,0x10000 4f02: 72 ec jb 4ef0 <main::h3a7d143d57a98e1aeaa+0x240> 4f04: 4c 39 f1 cmp rcx,r14 4f07: 75 b7 jne 4ec0 <main::h3a7d143d57a98e1aeaa+0x210> 4f09: eb 15 jmp 4f20 <main::h3a7d143d57a98e1aeaa+0x270> 4f0b: 48 8d 3d 5e 83 24 00 lea rdi,[rip+0x24835e] # 24d270 <panic_loc4648> 4f12: e8 89 65 03 00 call 3b4a0 <panicking::panic::h4265c0105caa1121SaM> 4f17: eb af jmp 4ec8 <main::h3a7d143d57a98e1aeaa+0x218> 4f19: 0f 1f 80 00 00 00 00 nop DWORD PTR [rax+0x0] 4f20: 4c 89 ed mov rbp,r13 4f23: 45 31 ff xor r15d,r15d 4f26: 66 2e 0f 1f 84 00 00 nop WORD PTR cs:[rax+rax*1+0x0] 4f2d: 00 00 00 4f30: 42 80 bc 3c c8 00 00 cmp BYTE PTR [rsp+r15*1+0xc8],0x0 4f37: 00 00 4f39: 75 56 jne 4f91 <main::h3a7d143d57a98e1aeaa+0x2e1> 4f3b: 48 89 6c 24 20 mov QWORD PTR [rsp+0x20],rbp 4f40: 48 8d 05 69 70 03 00 lea rax,[rip+0x37069] # 3bfb0 <fmt::num::usize.fmt..Display::fmt::h841af16830bb5f60kgW> 4f47: 48 89 44 24 30 mov QWORD PTR [rsp+0x30],rax 4f4c: 48 8d 44 24 20 lea rax,[rsp+0x20] 4f51: 48 89 44 24 28 mov QWORD PTR [rsp+0x28],rax 4f56: 48 8d 05 3b 83 24 00 lea rax,[rip+0x24833b] # 24d298 <ref4653> 4f5d: 48 89 44 24 38 mov QWORD PTR [rsp+0x38],rax 4f62: 48 c7 44 24 40 02 00 mov QWORD PTR [rsp+0x40],0x2 4f69: 00 00 4f6b: 48 8d 44 24 48 lea rax,[rsp+0x48] 4f70: 0f 57 c0 xorps xmm0,xmm0 4f73: 0f 11 00 movups XMMWORD PTR [rax],xmm0 4f76: 48 8d 44 24 28 lea rax,[rsp+0x28] 4f7b: 48 89 44 24 58 mov QWORD PTR [rsp+0x58],rax 4f80: 48 c7 44 24 60 01 00 mov QWORD PTR [rsp+0x60],0x1 4f87: 00 00 4f89: 4c 89 e7 mov rdi,r12 4f8c: e8 cf 2d 00 00 call 7d60 <io::stdio::_print::h27ae99cc97e67314Erh> 4f91: 49 ff c7 inc r15 4f94: 48 ff c5 inc rbp 4f97: 49 81 ff 00 00 01 00 cmp r15,0x10000 4f9e: 72 90 jb 4f30 <main::h3a7d143d57a98e1aeaa+0x280> 4fa0: 49 81 c5 00 00 01 00 add r13,0x10000 4fa7: 48 8b 44 24 18 mov rax,QWORD PTR [rsp+0x18] 4fac: 48 3d ff ff 00 00 cmp rax,0xffff 4fb2: 48 89 c3 mov rbx,rax 4fb5: 0f 86 c5 fe ff ff jbe 4e80 <main::h3a7d143d57a98e1aeaa+0x1d0> 4fbb: 48 8b b4 24 b8 00 00 mov rsi,QWORD PTR [rsp+0xb8] 4fc2: 00 4fc3: 48 85 f6 test rsi,rsi 4fc6: 74 22 je 4fea <main::h3a7d143d57a98e1aeaa+0x33a> 4fc8: 48 b8 1d 1d 1d 1d 1d movabs rax,0x1d1d1d1d1d1d1d1d 4fcf: 1d 1d 1d 4fd2: 48 39 c6 cmp rsi,rax 4fd5: 74 13 je 4fea <main::h3a7d143d57a98e1aeaa+0x33a> 4fd7: 48 c1 e6 03 shl rsi,0x3 4fdb: ba 08 00 00 00 mov edx,0x8 4fe0: 48 8b 7c 24 08 mov rdi,QWORD PTR [rsp+0x8] 4fe5: e8 26 12 01 00 call 16210 <__rust_deallocate> 4fea: 48 81 c4 c8 00 01 00 add rsp,0x100c8 4ff1: 5b pop rbx 4ff2: 41 5c pop r12 4ff4: 41 5d pop r13 4ff6: 41 5e pop r14 4ff8: 41 5f pop r15 4ffa: 5d pop rbp 4ffb: c3 ret 4ffc: 48 89 c3 mov rbx,rax 4fff: 48 8b b4 24 b8 00 00 mov rsi,QWORD PTR [rsp+0xb8] 5006: 00 5007: 48 85 f6 test rsi,rsi 500a: 74 25 je 5031 <main::h3a7d143d57a98e1aeaa+0x381> 500c: 48 b8 1d 1d 1d 1d 1d movabs rax,0x1d1d1d1d1d1d1d1d 5013: 1d 1d 1d 5016: 48 39 c6 cmp rsi,rax 5019: 74 16 je 5031 <main::h3a7d143d57a98e1aeaa+0x381> 501b: 48 c1 e6 03 shl rsi,0x3 501f: 48 8b bc 24 b0 00 00 mov rdi,QWORD PTR [rsp+0xb0] 5026: 00 5027: ba 08 00 00 00 mov edx,0x8 502c: e8 df 11 01 00 call 16210 <__rust_deallocate> 5031: 48 89 df mov rdi,rbx 5034: e8 e7 fa ff ff call 4b20 <_Unwind_Resume@plt> 5039: eb c1 jmp 4ffc <main::h3a7d143d57a98e1aeaa+0x34c> 503b: eb bf jmp 4ffc <main::h3a7d143d57a98e1aeaa+0x34c> 503d: 0f 1f 00 nop DWORD PTR [rax]
関連リンク
Raspberry Pi 3にChinachuをインストールするときのメモ
Raspberry Pi 3にChinachuをインストールする際、公式のインストールガイドのままではうまくインストールできないので、対処法のメモ。
ffmpegを自前でビルドする
commit 48afd7でスタティックビルド版のffmpegをインストールするようになっているが、スタティックビルド版にはarmhf版がない。 そこで、インストール時は自前ビルドを行う古いバージョンのスクリプトを用いるようにする。
$ wget https://github.com/kanreisa/Chinachu/raw/b34cbbf1eddf60be678ec3e5d441e7c3cb6818bc/chinachu -O chinachu_old $ chmod +x chinachu_old
コンパイルオプションを修正する
Raspberry Pi 3のCPUであるCortex-A53の場合、gccに-march=nativeオプションをつけるとクラッシュしてしまうバグが存在する。
また、nodeのビルドはコンパイルオプションがARMv7以下でないと失敗する。
そこで、-march=native
の代わりにRaspberry Pi 2と同等のコンパイルオプションを使うように修正する。
--- chinachu_old 2016-05-05 01:23:16.456616228 +0900 +++ chinachu_old 2016-05-05 01:23:22.606583914 +0900 @@ -77,8 +77,8 @@ ensure_dir "$USR_DIR/src" ensure_dir "$USR_DIR/bin" - export CFLAGS="-O2 -w -pipe -march=native" - export CXXFLAGS="-O2 -w -pipe -march=native" + export CFLAGS="-O2 -w -pipe -mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard" + export CXXFLAGS="-O2 -w -pipe -mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard" export MAKEFLAGS="-j $((`grep processor /proc/cpuinfo | wc -l` + 1)) -l 3" echo "Chinachu Installer Menu:"
上記の修正を加えたインストールスクリプトを実行することで、nodeおよびffmpegのビルドが正常に完了するようになる。
$ ./chinachu_old installer
C#+WPFでGUIアプリケーションを作ってみる
「JavaFX+FXMLでGUIアプリケーションを作ってみる」では、JavaFX+FXMLを使ってJavaランタイム(JRE)が入っている環境向けのGUIアプリケーションを作った。 ここでは、C#+WPFを使い、.NET Frameworkが入っている環境向けのGUIアプリケーションを作ってみる。
環境
Windows 8.1 Pro 64 bit版
>systeminfo OS 名: Microsoft Windows 8.1 Pro OS バージョン: 6.3.9600 N/A ビルド 9600 OS ビルドの種類: Multiprocessor Free システムの種類: x64-based PC プロセッサ: 1 プロセッサインストール済みです。 [01]: Intel64 Family 6 Model 69 Stepping 1 GenuineIntel ~1596 Mhz
Visual Studio Community 2015のインストール
まず、C# 6.0を使うために、Visual Studio Community 2015をインストールする。
HDD容量を節約するため、ここではインストール時のオプションとして「Custom」を選択し、C++開発に必要となる以下のコンポーネントのみをインストールした。
- 「Programming Languages」→「Visual C++」→「Common Tools for Visual C++ 2015」
- 「Windows and Web Development」→「Windows 8.1 and Windows Phone 8.0/8.1 Tools」→「Tools and Windows SDKs」
なお、C#を使うだけであればこれらも不要である。
インストールが終わったらOSを再起動し、アプリケーションメニューからVisual Studioを起動する。 初期設定はデフォルトで進めればよい。
GUIアプリケーションを作ってみる
「Java+SwingでGUIアプリケーションを作ってみる」と同様に、ドラッグアンドドロップされたファイルのSHA-1ハッシュ値をテーブルに表示するアプリケーションを書いてみる。
「File」→「New」→「Project」を開き、「Templates」→「Visual C#」→「Windows」から「WPF Application」を選択する。 さらに、名前を「SHA1CalculatorWPF」としてOKを押し、プロジェクトを作成する。
まず、MainWindow.xaml
について、ToolBoxからDataGridを選択し配置する。
また、WindowのTitle属性を「MainWindow」から「SHA-1 Calculator WPF」に書き換える。
さらに他のコードを書きながら編集していくと、最終的には次のようなコードとなる。
<Window x:Class="SHA1CalculatorWPF.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:SHA1CalculatorWPF" mc:Ignorable="d" Title="SHA-1 Calculator WPF" Height="350" Width="640"> <Grid AllowDrop="True" DragOver="Grid_DragOver" Drop="Grid_Drop"> <DataGrid x:Name="dataGrid" AutoGenerateColumns="False" CanUserResizeRows="False"> <DataGrid.Columns> <DataGridTextColumn Header="File Path" Binding="{Binding Path}" Width="*"/> <DataGridTextColumn Header="sha1sum" Binding="{Binding Sha1sum}" Width="*"/> </DataGrid.Columns> </DataGrid> </Grid> </Window>
GridのDragOver、Drop属性が、次のコードで定義しているハンドラ関数に対応する。 また、DataGridTextColumnのBinding属性で指定した変数が、FileInfoクラスのメンバ変数に対応する。
MainWindow.xaml.cs
を開き、動作を記述するコードを書くと次のようになる。
using System; using System.Collections.ObjectModel; using System.ComponentModel; using System.IO; using System.Runtime.CompilerServices; using System.Windows; namespace SHA1CalculatorWPF { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { ObservableCollection<FileInfo> fileList; public class FileInfo : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged([CallerMemberName] String propertyName = "") { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } public string Path { get; set; } private string _sha1sum; public string Sha1sum { get { return _sha1sum; } set { if (value != _sha1sum) { _sha1sum = value; NotifyPropertyChanged(); } } } } public MainWindow() { InitializeComponent(); fileList = new ObservableCollection<FileInfo>(); dataGrid.ItemsSource = fileList; } private void Grid_DragOver(object sender, DragEventArgs e) { if (e.Data.GetDataPresent(DataFormats.FileDrop)) { e.Effects = DragDropEffects.Copy; } else { e.Effects = DragDropEffects.None; } e.Handled = false; } private void Grid_Drop(object sender, DragEventArgs e) { if (e.Data.GetDataPresent(DataFormats.FileDrop)) { var paths = (string[])e.Data.GetData(DataFormats.FileDrop); foreach (var path in paths) { var fileinfo = new FileInfo { Path = path, Sha1sum = "" }; fileList.Add(fileinfo); var worker = new BackgroundWorker(); worker.DoWork += worker_DoWork; worker.RunWorkerAsync(fileinfo); } } } void worker_DoWork(object sender, DoWorkEventArgs e) { // update digest with each 8MB chunk var fileinfo = (FileInfo)e.Argument; var fs = new FileStream(fileinfo.Path, FileMode.Open, FileAccess.Read); var sha1 = new System.Security.Cryptography.SHA1Managed(); var buf = new byte[8 * 1024 * 1024]; int n = fs.Read(buf, 0, buf.Length); while (fs.Position < fs.Length) { sha1.TransformBlock(buf, 0, n, buf, 0); fileinfo.Sha1sum = string.Format("Calculating {0}%...", 100L * fs.Position / fs.Length); n = fs.Read(buf, 0, buf.Length); } sha1.TransformFinalBlock(buf, 0, n); fileinfo.Sha1sum = BitConverter.ToString(sha1.Hash).Replace("-", "").ToLower(); } } }
上のコードでは、ObservableCollection
をDataGridのItemsSource
にセットすることで、データバインディングを行っている。
ただし、FileInfoクラスのメンバ変数の変更までは即座にビューに反映されないため、FileInfo
クラスにもINotifyPropertyChanged
インタフェースを実装する必要がある。
そして、プロパティのsetterの中でPropertyChangedEventHandler
を呼ぶことにより、更新をビューに通知する。
また、バッググラウンドスレッドを生成するには、BackgroundWorker
を使う。
SHA-1ハッシュの計算には.NET基盤(CLR)上で計算するSHA1Managed
クラスとWindows APIを利用するSHA1CryptoServiceProvider
、SHA1Cng
クラスが使えるが、基本的にはSHA1Managed
を使えばよい(参考)。
コードを保存した後「Start」を押して実行し、適当にファイルをドラッグアンドドロップした後のスクリーンショットを次に示す。
進捗を表す文字列がビューにリアルタイムで表示され、ハッシュ値が計算できていることが確認できる。
実行可能なexeファイルを作成する
ビルド設定を「Debug」から「Release」に変えてビルドすることで、プロジェクトフォルダのSHA1CalculatorWPF\bin\Release
以下にデバッグ情報を含まないexeファイルが生成される。
また、メニューの「Build」→「Publish SHA1CalculatorWPF」を選ぶことで、ClickOnceインストーラを作成することもできる。
生成されたexeファイルを実行すると、上と同様のウィンドウが表示されることが確認できる。
関連リンク
- WPF4.5入門 その62「まとめ」 - かずきのBlog@hatena
- [WPF]DataGridへのBindingに関する基本設計 | OITA: Oika's Information Technological Activities
- INotifyPropertyChanged, The .NET 4.6 Way | DanRigby.com
- [MVVM] 便利で間違えのないプロパティ変更通知を行うBindableBaseの実装 – Tech.D-ITlab | Denso IT Laboratory researcher's blog sites
- How to: Open a File That is Dropped on a RichTextBox Control
objdumpのdiffをいい感じに取る方法のメモ
たとえば、次のような二つのC言語コードを考える。
/* test1.c */ #include <stdio.h> double divide(long x, long y) { return x/(double)y; } int main() { divide(1, 2); divide(1, 0); return 0; }
/* test2.c */ #include <stdio.h> #include <stdlib.h> double divide(long x, long y) { if (!y) { exit(1); } return x/(double)y; } int main() { divide(1, 2); divide(1, 0); return 0; }
二つ目のコードは、被除数が0かどうかのチェックを加えたものである。 これらをそれぞれコンパイルし、objdumpで逆アセンブルしたもののdiffを取ると次のようになる。
$ make test1 test2 cc test1.c -o test1 cc test2.c -o test2 $ diff -u <(objdump -d test1) <(objdump -d test2) --- /dev/fd/63 2016-04-30 07:28:59.852032082 +0900 +++ /dev/fd/62 2016-04-30 07:28:59.852032082 +0900 @@ -1,193 +1,202 @@ -test1: file format elf64-x86-64 +test2: file format elf64-x86-64 Disassembly of section .init: -00000000004003a8 <_init>: - 4003a8: 48 83 ec 08 sub rsp,0x8 - 4003ac: 48 8b 05 45 0c 20 00 mov rax,QWORD PTR [rip+0x200c45] # 600ff8 <_DYNAMIC+0x1d0> - 4003b3: 48 85 c0 test rax,rax - 4003b6: 74 05 je 4003bd <_init+0x15> - 4003b8: e8 33 00 00 00 call 4003f0 <__gmon_start__@plt> - 4003bd: 48 83 c4 08 add rsp,0x8 - 4003c1: c3 ret +00000000004003e0 <_init>: + 4003e0: 48 83 ec 08 sub rsp,0x8 + 4003e4: 48 8b 05 0d 0c 20 00 mov rax,QWORD PTR [rip+0x200c0d] # 600ff8 <_DYNAMIC+0x1d0> + 4003eb: 48 85 c0 test rax,rax + 4003ee: 74 05 je 4003f5 <_init+0x15> + 4003f0: e8 2b 00 00 00 call 400420 <__gmon_start__@plt> + 4003f5: 48 83 c4 08 add rsp,0x8 + 4003f9: c3 ret Disassembly of section .plt: -00000000004003d0 <__libc_start_main@plt-0x10>: - 4003d0: ff 35 32 0c 20 00 push QWORD PTR [rip+0x200c32] # 601008 <_GLOBAL_OFFSET_TABLE_+0x8> - 4003d6: ff 25 34 0c 20 00 jmp QWORD PTR [rip+0x200c34] # 601010 <_GLOBAL_OFFSET_TABLE_+0x10> - 4003dc: 0f 1f 40 00 nop DWORD PTR [rax+0x0] - (snip)
主にアドレス部分のずれにより、まったくdiffが取れていないことがわかる。
このような場合、次のようなコマンドを打つとよい。
$ diff -u1 -F '>:$' -I '[0-9a-f]\{6,\}' <(objdump -d test1 | cut -f2-) <(objdump -d test2 | cut -f2-) --- /dev/fd/63 2016-04-30 07:40:28.072016196 +0900 +++ /dev/fd/62 2016-04-30 07:40:28.072016196 +0900 @@ -1,3 +1,3 @@ -test1: file format elf64-x86-64 +test2: file format elf64-x86-64 @@ -30,3 +30,8 @@ 00000000004003f0 <__gmon_start__@plt>: 68 01 00 00 00 push 0x1 -e9 d0 ff ff ff jmp 4003d0 <_init+0x28> +e9 d0 ff ff ff jmp 400400 <_init+0x20> + +0000000000400430 <exit@plt>: +ff 25 f2 0b 20 00 jmp QWORD PTR [rip+0x200bf2] # 601028 <_GLOBAL_OFFSET_TABLE_+0x28> +68 02 00 00 00 push 0x2 +e9 c0 ff ff ff jmp 400400 <_init+0x20> @@ -118,4 +123,9 @@ 00000000004004ed <divide>: 48 89 e5 mov rbp,rsp +48 83 ec 20 sub rsp,0x20 48 89 7d f8 mov QWORD PTR [rbp-0x8],rdi 48 89 75 f0 mov QWORD PTR [rbp-0x10],rsi +48 83 7d f0 00 cmp QWORD PTR [rbp-0x10],0x0 +75 0a jne 40054e <divide+0x21> +bf 01 00 00 00 mov edi,0x1 +e8 e2 fe ff ff call 400430 <exit@plt> f2 48 0f 2a 45 f8 cvtsi2sd xmm0,QWORD PTR [rbp-0x8] @@ -127,3 +137,3 @@ 00000000004004ed <divide>: f2 0f 10 45 e8 movsd xmm0,QWORD PTR [rbp-0x18] -5d pop rbp +c9 leave c3 ret @@ -142,4 +152,3 @@ 000000000040051d <main>: c3 ret -66 2e 0f 1f 84 00 00 nop WORD PTR cs:[rax+rax*1+0x0] -00 00 00 +0f 1f 44 00 00 nop DWORD PTR [rax+rax*1+0x0]
-u1
は差分の前後1行のみを表示させるオプション、-F
は正規表現にマッチする行をセクション見出しとして扱うオプション、-I
は正規表現にマッチする行のみの差分を除外するオプションである。