├── LICENSE ├── README.md ├── extract-pw.py ├── outdated ├── seagate-dump.py └── seagate-ng.py ├── requirements.txt ├── see-append.py ├── see.py ├── wgetstyle.py └── wip ├── extract-seagate-password.py └── seaget.py /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 2.1, February 1999 3 | 4 | Copyright (C) 1991, 1999 Free Software Foundation, Inc. 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | [This is the first released version of the Lesser GPL. It also counts 10 | as the successor of the GNU Library Public License, version 2, hence 11 | the version number 2.1.] 12 | 13 | Preamble 14 | 15 | The licenses for most software are designed to take away your 16 | freedom to share and change it. By contrast, the GNU General Public 17 | Licenses are intended to guarantee your freedom to share and change 18 | free software--to make sure the software is free for all its users. 19 | 20 | This license, the Lesser General Public License, applies to some 21 | specially designated software packages--typically libraries--of the 22 | Free Software Foundation and other authors who decide to use it. You 23 | can use it too, but we suggest you first think carefully about whether 24 | this license or the ordinary General Public License is the better 25 | strategy to use in any particular case, based on the explanations below. 26 | 27 | When we speak of free software, we are referring to freedom of use, 28 | not price. Our General Public Licenses are designed to make sure that 29 | you have the freedom to distribute copies of free software (and charge 30 | for this service if you wish); that you receive source code or can get 31 | it if you want it; that you can change the software and use pieces of 32 | it in new free programs; and that you are informed that you can do 33 | these things. 34 | 35 | To protect your rights, we need to make restrictions that forbid 36 | distributors to deny you these rights or to ask you to surrender these 37 | rights. These restrictions translate to certain responsibilities for 38 | you if you distribute copies of the library or if you modify it. 39 | 40 | For example, if you distribute copies of the library, whether gratis 41 | or for a fee, you must give the recipients all the rights that we gave 42 | you. You must make sure that they, too, receive or can get the source 43 | code. If you link other code with the library, you must provide 44 | complete object files to the recipients, so that they can relink them 45 | with the library after making changes to the library and recompiling 46 | it. And you must show them these terms so they know their rights. 47 | 48 | We protect your rights with a two-step method: (1) we copyright the 49 | library, and (2) we offer you this license, which gives you legal 50 | permission to copy, distribute and/or modify the library. 51 | 52 | To protect each distributor, we want to make it very clear that 53 | there is no warranty for the free library. Also, if the library is 54 | modified by someone else and passed on, the recipients should know 55 | that what they have is not the original version, so that the original 56 | author's reputation will not be affected by problems that might be 57 | introduced by others. 58 | 59 | Finally, software patents pose a constant threat to the existence of 60 | any free program. We wish to make sure that a company cannot 61 | effectively restrict the users of a free program by obtaining a 62 | restrictive license from a patent holder. Therefore, we insist that 63 | any patent license obtained for a version of the library must be 64 | consistent with the full freedom of use specified in this license. 65 | 66 | Most GNU software, including some libraries, is covered by the 67 | ordinary GNU General Public License. This license, the GNU Lesser 68 | General Public License, applies to certain designated libraries, and 69 | is quite different from the ordinary General Public License. We use 70 | this license for certain libraries in order to permit linking those 71 | libraries into non-free programs. 72 | 73 | When a program is linked with a library, whether statically or using 74 | a shared library, the combination of the two is legally speaking a 75 | combined work, a derivative of the original library. The ordinary 76 | General Public License therefore permits such linking only if the 77 | entire combination fits its criteria of freedom. The Lesser General 78 | Public License permits more lax criteria for linking other code with 79 | the library. 80 | 81 | We call this license the "Lesser" General Public License because it 82 | does Less to protect the user's freedom than the ordinary General 83 | Public License. It also provides other free software developers Less 84 | of an advantage over competing non-free programs. These disadvantages 85 | are the reason we use the ordinary General Public License for many 86 | libraries. However, the Lesser license provides advantages in certain 87 | special circumstances. 88 | 89 | For example, on rare occasions, there may be a special need to 90 | encourage the widest possible use of a certain library, so that it becomes 91 | a de-facto standard. To achieve this, non-free programs must be 92 | allowed to use the library. A more frequent case is that a free 93 | library does the same job as widely used non-free libraries. In this 94 | case, there is little to gain by limiting the free library to free 95 | software only, so we use the Lesser General Public License. 96 | 97 | In other cases, permission to use a particular library in non-free 98 | programs enables a greater number of people to use a large body of 99 | free software. For example, permission to use the GNU C Library in 100 | non-free programs enables many more people to use the whole GNU 101 | operating system, as well as its variant, the GNU/Linux operating 102 | system. 103 | 104 | Although the Lesser General Public License is Less protective of the 105 | users' freedom, it does ensure that the user of a program that is 106 | linked with the Library has the freedom and the wherewithal to run 107 | that program using a modified version of the Library. 108 | 109 | The precise terms and conditions for copying, distribution and 110 | modification follow. Pay close attention to the difference between a 111 | "work based on the library" and a "work that uses the library". The 112 | former contains code derived from the library, whereas the latter must 113 | be combined with the library in order to run. 114 | 115 | GNU LESSER GENERAL PUBLIC LICENSE 116 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 117 | 118 | 0. This License Agreement applies to any software library or other 119 | program which contains a notice placed by the copyright holder or 120 | other authorized party saying it may be distributed under the terms of 121 | this Lesser General Public License (also called "this License"). 122 | Each licensee is addressed as "you". 123 | 124 | A "library" means a collection of software functions and/or data 125 | prepared so as to be conveniently linked with application programs 126 | (which use some of those functions and data) to form executables. 127 | 128 | The "Library", below, refers to any such software library or work 129 | which has been distributed under these terms. A "work based on the 130 | Library" means either the Library or any derivative work under 131 | copyright law: that is to say, a work containing the Library or a 132 | portion of it, either verbatim or with modifications and/or translated 133 | straightforwardly into another language. (Hereinafter, translation is 134 | included without limitation in the term "modification".) 135 | 136 | "Source code" for a work means the preferred form of the work for 137 | making modifications to it. For a library, complete source code means 138 | all the source code for all modules it contains, plus any associated 139 | interface definition files, plus the scripts used to control compilation 140 | and installation of the library. 141 | 142 | Activities other than copying, distribution and modification are not 143 | covered by this License; they are outside its scope. The act of 144 | running a program using the Library is not restricted, and output from 145 | such a program is covered only if its contents constitute a work based 146 | on the Library (independent of the use of the Library in a tool for 147 | writing it). Whether that is true depends on what the Library does 148 | and what the program that uses the Library does. 149 | 150 | 1. You may copy and distribute verbatim copies of the Library's 151 | complete source code as you receive it, in any medium, provided that 152 | you conspicuously and appropriately publish on each copy an 153 | appropriate copyright notice and disclaimer of warranty; keep intact 154 | all the notices that refer to this License and to the absence of any 155 | warranty; and distribute a copy of this License along with the 156 | Library. 157 | 158 | You may charge a fee for the physical act of transferring a copy, 159 | and you may at your option offer warranty protection in exchange for a 160 | fee. 161 | 162 | 2. You may modify your copy or copies of the Library or any portion 163 | of it, thus forming a work based on the Library, and copy and 164 | distribute such modifications or work under the terms of Section 1 165 | above, provided that you also meet all of these conditions: 166 | 167 | a) The modified work must itself be a software library. 168 | 169 | b) You must cause the files modified to carry prominent notices 170 | stating that you changed the files and the date of any change. 171 | 172 | c) You must cause the whole of the work to be licensed at no 173 | charge to all third parties under the terms of this License. 174 | 175 | d) If a facility in the modified Library refers to a function or a 176 | table of data to be supplied by an application program that uses 177 | the facility, other than as an argument passed when the facility 178 | is invoked, then you must make a good faith effort to ensure that, 179 | in the event an application does not supply such function or 180 | table, the facility still operates, and performs whatever part of 181 | its purpose remains meaningful. 182 | 183 | (For example, a function in a library to compute square roots has 184 | a purpose that is entirely well-defined independent of the 185 | application. Therefore, Subsection 2d requires that any 186 | application-supplied function or table used by this function must 187 | be optional: if the application does not supply it, the square 188 | root function must still compute square roots.) 189 | 190 | These requirements apply to the modified work as a whole. If 191 | identifiable sections of that work are not derived from the Library, 192 | and can be reasonably considered independent and separate works in 193 | themselves, then this License, and its terms, do not apply to those 194 | sections when you distribute them as separate works. But when you 195 | distribute the same sections as part of a whole which is a work based 196 | on the Library, the distribution of the whole must be on the terms of 197 | this License, whose permissions for other licensees extend to the 198 | entire whole, and thus to each and every part regardless of who wrote 199 | it. 200 | 201 | Thus, it is not the intent of this section to claim rights or contest 202 | your rights to work written entirely by you; rather, the intent is to 203 | exercise the right to control the distribution of derivative or 204 | collective works based on the Library. 205 | 206 | In addition, mere aggregation of another work not based on the Library 207 | with the Library (or with a work based on the Library) on a volume of 208 | a storage or distribution medium does not bring the other work under 209 | the scope of this License. 210 | 211 | 3. You may opt to apply the terms of the ordinary GNU General Public 212 | License instead of this License to a given copy of the Library. To do 213 | this, you must alter all the notices that refer to this License, so 214 | that they refer to the ordinary GNU General Public License, version 2, 215 | instead of to this License. (If a newer version than version 2 of the 216 | ordinary GNU General Public License has appeared, then you can specify 217 | that version instead if you wish.) Do not make any other change in 218 | these notices. 219 | 220 | Once this change is made in a given copy, it is irreversible for 221 | that copy, so the ordinary GNU General Public License applies to all 222 | subsequent copies and derivative works made from that copy. 223 | 224 | This option is useful when you wish to copy part of the code of 225 | the Library into a program that is not a library. 226 | 227 | 4. You may copy and distribute the Library (or a portion or 228 | derivative of it, under Section 2) in object code or executable form 229 | under the terms of Sections 1 and 2 above provided that you accompany 230 | it with the complete corresponding machine-readable source code, which 231 | must be distributed under the terms of Sections 1 and 2 above on a 232 | medium customarily used for software interchange. 233 | 234 | If distribution of object code is made by offering access to copy 235 | from a designated place, then offering equivalent access to copy the 236 | source code from the same place satisfies the requirement to 237 | distribute the source code, even though third parties are not 238 | compelled to copy the source along with the object code. 239 | 240 | 5. A program that contains no derivative of any portion of the 241 | Library, but is designed to work with the Library by being compiled or 242 | linked with it, is called a "work that uses the Library". Such a 243 | work, in isolation, is not a derivative work of the Library, and 244 | therefore falls outside the scope of this License. 245 | 246 | However, linking a "work that uses the Library" with the Library 247 | creates an executable that is a derivative of the Library (because it 248 | contains portions of the Library), rather than a "work that uses the 249 | library". The executable is therefore covered by this License. 250 | Section 6 states terms for distribution of such executables. 251 | 252 | When a "work that uses the Library" uses material from a header file 253 | that is part of the Library, the object code for the work may be a 254 | derivative work of the Library even though the source code is not. 255 | Whether this is true is especially significant if the work can be 256 | linked without the Library, or if the work is itself a library. The 257 | threshold for this to be true is not precisely defined by law. 258 | 259 | If such an object file uses only numerical parameters, data 260 | structure layouts and accessors, and small macros and small inline 261 | functions (ten lines or less in length), then the use of the object 262 | file is unrestricted, regardless of whether it is legally a derivative 263 | work. (Executables containing this object code plus portions of the 264 | Library will still fall under Section 6.) 265 | 266 | Otherwise, if the work is a derivative of the Library, you may 267 | distribute the object code for the work under the terms of Section 6. 268 | Any executables containing that work also fall under Section 6, 269 | whether or not they are linked directly with the Library itself. 270 | 271 | 6. As an exception to the Sections above, you may also combine or 272 | link a "work that uses the Library" with the Library to produce a 273 | work containing portions of the Library, and distribute that work 274 | under terms of your choice, provided that the terms permit 275 | modification of the work for the customer's own use and reverse 276 | engineering for debugging such modifications. 277 | 278 | You must give prominent notice with each copy of the work that the 279 | Library is used in it and that the Library and its use are covered by 280 | this License. You must supply a copy of this License. If the work 281 | during execution displays copyright notices, you must include the 282 | copyright notice for the Library among them, as well as a reference 283 | directing the user to the copy of this License. Also, you must do one 284 | of these things: 285 | 286 | a) Accompany the work with the complete corresponding 287 | machine-readable source code for the Library including whatever 288 | changes were used in the work (which must be distributed under 289 | Sections 1 and 2 above); and, if the work is an executable linked 290 | with the Library, with the complete machine-readable "work that 291 | uses the Library", as object code and/or source code, so that the 292 | user can modify the Library and then relink to produce a modified 293 | executable containing the modified Library. (It is understood 294 | that the user who changes the contents of definitions files in the 295 | Library will not necessarily be able to recompile the application 296 | to use the modified definitions.) 297 | 298 | b) Use a suitable shared library mechanism for linking with the 299 | Library. A suitable mechanism is one that (1) uses at run time a 300 | copy of the library already present on the user's computer system, 301 | rather than copying library functions into the executable, and (2) 302 | will operate properly with a modified version of the library, if 303 | the user installs one, as long as the modified version is 304 | interface-compatible with the version that the work was made with. 305 | 306 | c) Accompany the work with a written offer, valid for at 307 | least three years, to give the same user the materials 308 | specified in Subsection 6a, above, for a charge no more 309 | than the cost of performing this distribution. 310 | 311 | d) If distribution of the work is made by offering access to copy 312 | from a designated place, offer equivalent access to copy the above 313 | specified materials from the same place. 314 | 315 | e) Verify that the user has already received a copy of these 316 | materials or that you have already sent this user a copy. 317 | 318 | For an executable, the required form of the "work that uses the 319 | Library" must include any data and utility programs needed for 320 | reproducing the executable from it. However, as a special exception, 321 | the materials to be distributed need not include anything that is 322 | normally distributed (in either source or binary form) with the major 323 | components (compiler, kernel, and so on) of the operating system on 324 | which the executable runs, unless that component itself accompanies 325 | the executable. 326 | 327 | It may happen that this requirement contradicts the license 328 | restrictions of other proprietary libraries that do not normally 329 | accompany the operating system. Such a contradiction means you cannot 330 | use both them and the Library together in an executable that you 331 | distribute. 332 | 333 | 7. You may place library facilities that are a work based on the 334 | Library side-by-side in a single library together with other library 335 | facilities not covered by this License, and distribute such a combined 336 | library, provided that the separate distribution of the work based on 337 | the Library and of the other library facilities is otherwise 338 | permitted, and provided that you do these two things: 339 | 340 | a) Accompany the combined library with a copy of the same work 341 | based on the Library, uncombined with any other library 342 | facilities. This must be distributed under the terms of the 343 | Sections above. 344 | 345 | b) Give prominent notice with the combined library of the fact 346 | that part of it is a work based on the Library, and explaining 347 | where to find the accompanying uncombined form of the same work. 348 | 349 | 8. You may not copy, modify, sublicense, link with, or distribute 350 | the Library except as expressly provided under this License. Any 351 | attempt otherwise to copy, modify, sublicense, link with, or 352 | distribute the Library is void, and will automatically terminate your 353 | rights under this License. However, parties who have received copies, 354 | or rights, from you under this License will not have their licenses 355 | terminated so long as such parties remain in full compliance. 356 | 357 | 9. You are not required to accept this License, since you have not 358 | signed it. However, nothing else grants you permission to modify or 359 | distribute the Library or its derivative works. These actions are 360 | prohibited by law if you do not accept this License. Therefore, by 361 | modifying or distributing the Library (or any work based on the 362 | Library), you indicate your acceptance of this License to do so, and 363 | all its terms and conditions for copying, distributing or modifying 364 | the Library or works based on it. 365 | 366 | 10. Each time you redistribute the Library (or any work based on the 367 | Library), the recipient automatically receives a license from the 368 | original licensor to copy, distribute, link with or modify the Library 369 | subject to these terms and conditions. You may not impose any further 370 | restrictions on the recipients' exercise of the rights granted herein. 371 | You are not responsible for enforcing compliance by third parties with 372 | this License. 373 | 374 | 11. If, as a consequence of a court judgment or allegation of patent 375 | infringement or for any other reason (not limited to patent issues), 376 | conditions are imposed on you (whether by court order, agreement or 377 | otherwise) that contradict the conditions of this License, they do not 378 | excuse you from the conditions of this License. If you cannot 379 | distribute so as to satisfy simultaneously your obligations under this 380 | License and any other pertinent obligations, then as a consequence you 381 | may not distribute the Library at all. For example, if a patent 382 | license would not permit royalty-free redistribution of the Library by 383 | all those who receive copies directly or indirectly through you, then 384 | the only way you could satisfy both it and this License would be to 385 | refrain entirely from distribution of the Library. 386 | 387 | If any portion of this section is held invalid or unenforceable under any 388 | particular circumstance, the balance of the section is intended to apply, 389 | and the section as a whole is intended to apply in other circumstances. 390 | 391 | It is not the purpose of this section to induce you to infringe any 392 | patents or other property right claims or to contest validity of any 393 | such claims; this section has the sole purpose of protecting the 394 | integrity of the free software distribution system which is 395 | implemented by public license practices. Many people have made 396 | generous contributions to the wide range of software distributed 397 | through that system in reliance on consistent application of that 398 | system; it is up to the author/donor to decide if he or she is willing 399 | to distribute software through any other system and a licensee cannot 400 | impose that choice. 401 | 402 | This section is intended to make thoroughly clear what is believed to 403 | be a consequence of the rest of this License. 404 | 405 | 12. If the distribution and/or use of the Library is restricted in 406 | certain countries either by patents or by copyrighted interfaces, the 407 | original copyright holder who places the Library under this License may add 408 | an explicit geographical distribution limitation excluding those countries, 409 | so that distribution is permitted only in or among countries not thus 410 | excluded. In such case, this License incorporates the limitation as if 411 | written in the body of this License. 412 | 413 | 13. The Free Software Foundation may publish revised and/or new 414 | versions of the Lesser General Public License from time to time. 415 | Such new versions will be similar in spirit to the present version, 416 | but may differ in detail to address new problems or concerns. 417 | 418 | Each version is given a distinguishing version number. If the Library 419 | specifies a version number of this License which applies to it and 420 | "any later version", you have the option of following the terms and 421 | conditions either of that version or of any later version published by 422 | the Free Software Foundation. If the Library does not specify a 423 | license version number, you may choose any version ever published by 424 | the Free Software Foundation. 425 | 426 | 14. If you wish to incorporate parts of the Library into other free 427 | programs whose distribution conditions are incompatible with these, 428 | write to the author to ask for permission. For software which is 429 | copyrighted by the Free Software Foundation, write to the Free 430 | Software Foundation; we sometimes make exceptions for this. Our 431 | decision will be guided by the two goals of preserving the free status 432 | of all derivatives of our free software and of promoting the sharing 433 | and reuse of software generally. 434 | 435 | NO WARRANTY 436 | 437 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO 438 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. 439 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR 440 | OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY 441 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE 442 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 443 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE 444 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME 445 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 446 | 447 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN 448 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY 449 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU 450 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR 451 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE 452 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING 453 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A 454 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF 455 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 456 | DAMAGES. 457 | 458 | END OF TERMS AND CONDITIONS 459 | 460 | How to Apply These Terms to Your New Libraries 461 | 462 | If you develop a new library, and you want it to be of the greatest 463 | possible use to the public, we recommend making it free software that 464 | everyone can redistribute and change. You can do so by permitting 465 | redistribution under these terms (or, alternatively, under the terms of the 466 | ordinary General Public License). 467 | 468 | To apply these terms, attach the following notices to the library. It is 469 | safest to attach them to the start of each source file to most effectively 470 | convey the exclusion of warranty; and each file should have at least the 471 | "copyright" line and a pointer to where the full notice is found. 472 | 473 | Wget like tool to dump seagate memory and buffer 474 | Copyright (C) 2013 Thomas Schneider 475 | 476 | This library is free software; you can redistribute it and/or 477 | modify it under the terms of the GNU Lesser General Public 478 | License as published by the Free Software Foundation; either 479 | version 2.1 of the License, or (at your option) any later version. 480 | 481 | This library is distributed in the hope that it will be useful, 482 | but WITHOUT ANY WARRANTY; without even the implied warranty of 483 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 484 | Lesser General Public License for more details. 485 | 486 | You should have received a copy of the GNU Lesser General Public 487 | License along with this library; if not, write to the Free Software 488 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 489 | 490 | Also add information on how to contact you by electronic and paper mail. 491 | 492 | You should also get your employer (if you work as a programmer) or your 493 | school, if any, to sign a "copyright disclaimer" for the library, if 494 | necessary. Here is a sample; alter the names: 495 | 496 | Yoyodyne, Inc., hereby disclaims all copyright interest in the 497 | library `Frob' (a library for tweaking knobs) written by James Random Hacker. 498 | 499 | {signature of Ty Coon}, 1 April 1990 500 | Ty Coon, President of Vice 501 | 502 | That's all there is to it! 503 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | seaget 2 | ====== 3 | 4 | Wget like tool to dump seagate memory and buffer 5 | This are all the scripts I hacked together.This is neither refined nor cleaned. 6 | 7 | Usage is simple:
8 | python2 see.py device dumpfile baud 9 | 10 | Default baud should be 38400 maximum is 115200 11 | 12 | If you have problems dumping anything you can set the timeout in see.py to something higher. 13 | timeout=1 should work with every hardware. 14 | -------------------------------------------------------------------------------- /extract-pw.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python2 2 | import re 3 | import sys 4 | import binascii 5 | 6 | f=binascii.hexlify(open(sys.argv[1],'r').read()) 7 | pwsR=re.compile('00000000edfe0d90ffff.+?00000c54.{8}(.{64})(.{64})') 8 | pws=pwsR.findall(f) 9 | for pw in pws[0]: 10 | print pw 11 | print pw.decode("hex") 12 | -------------------------------------------------------------------------------- /outdated/seagate-dump.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python2 2 | #Dumps the memory of a seagate hd using the jumper pin serial interface 3 | import serial 4 | import sys,os,re 5 | import time 6 | 7 | try: 8 | device=sys.argv[1] 9 | dumpfile=sys.argv[2] 10 | except: 11 | print 'Usage:' 12 | print sys.argv[0]+' device dumpfile' 13 | quit() 14 | baud=38400 15 | mem=open(dumpfile,'w') 16 | ser = serial.Serial(port=device, baudrate=baud, bytesize=8,parity='N',stopbits=1,timeout=1) 17 | #ser = serial.Serial(port=device, baudrate=baud, timeout=1, xonxoff=False, rtscts=False, dsrdtr=True) 18 | 19 | #ser.write(unicode("A\n")) 20 | #set right diagnostic mode 21 | ser.write(unicode("/1\n")) 22 | i=0 23 | dumpf="" 24 | while 1: 25 | # print ser.isOpen() 26 | # ser.write(unicode("A\n")) 27 | try: 28 | arr = ser.readline() 29 | if arr!="": 30 | # sys.stdout.write(arr) 31 | # sys.stdout.flush() 32 | # mem.write(arr) 33 | dumpf=dumpf+arr 34 | else: 35 | ser.write("D0,"+str(hex(512*i)[2:])+"\n") 36 | i=i+1 37 | print 'Dumping address '+str(hex(512*i)[2:])+' '+str(320*i/1000)+'kB' 38 | except: 39 | print 'Saving this shit right where it belongs!' 40 | # mem.close() 41 | break 42 | 43 | fooR=re.compile('\d\d\d\d\d\d\d\d\s+(.+)\r') 44 | foo=fooR.findall(dumpf) 45 | for line in foo: 46 | mem.write(re.sub(' ','',line).decode("hex")) 47 | mem.close 48 | print 'Succesfully dumped file' 49 | -------------------------------------------------------------------------------- /outdated/seagate-ng.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python2 2 | #Dumps the memory of a seagate hd using the jumper pin serial interface 3 | import serial 4 | import sys,os,re 5 | import time 6 | 7 | try: 8 | device=sys.argv[1] 9 | dumpfile=sys.argv[2] 10 | except: 11 | print 'Usage:' 12 | print sys.argv[0]+' device dumpfile' 13 | quit() 14 | baud=38400 15 | mem=open(dumpfile,'w') 16 | ser = serial.Serial(port=device, baudrate=baud, bytesize=8,parity='N',stopbits=1,timeout=0.1) 17 | #ser = serial.Serial(port=device, baudrate=baud, timeout=1, xonxoff=False, rtscts=False, dsrdtr=True) 18 | 19 | #ser.write(unicode("A\n")) 20 | #set right diagnostic mode 21 | ser.write("\x1A\n") 22 | while ser.inWaiting()!=0: 23 | print ser.readline(ser.inWaiting()) 24 | 25 | ser.write("/T\n") 26 | while ser.inWaiting()!=0: 27 | print ser.readline(ser.inWaiting()) 28 | ser.write("B115200\n") 29 | while ser.inWaiting()!=0: 30 | print ser.readline(ser.inWaiting()) 31 | baud=115200 32 | ser = serial.Serial(port=device, baudrate=baud, bytesize=8,parity='N',stopbits=1,timeout=0.1) 33 | 34 | 35 | print 'FLUUUUSHHHHH' 36 | ser.write(unicode("/1\n")) 37 | #ser.write(unicode("^E\n")) 38 | print 'Waiting for '+str(ser.inWaiting()) 39 | ser.readline(ser.inWaiting()) 40 | print 'Waiting for '+str(ser.inWaiting())+' foos in output to be flushed' 41 | full=ser.inWaiting() 42 | while ser.inWaiting()!=0: 43 | sys.stdout.write('\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b') 44 | sys.stdout.write('Flushing '+str((100/full)*(full-ser.inWaiting()))+'%') 45 | sys.stdout.flush() 46 | ser.readline(ser.inWaiting()) 47 | print '' 48 | print 'Done Flushing :)' 49 | print str(ser.inWaiting())+' remaining' 50 | #ser.write("A\n") 51 | #ser.setBreak() 52 | i=0 53 | dumpf="" 54 | zeit=time.time() 55 | zz=zeit 56 | while 1: 57 | # print ser.isOpen() 58 | # ser.write(unicode("A\n")) 59 | try: 60 | arr = ser.readline() 61 | if arr!="": 62 | # sys.stdout.write(arr) 63 | # sys.stdout.flush() 64 | # mem.write(arr) 65 | dumpf=dumpf+arr 66 | else: 67 | speed=256/(zz-time.time()) 68 | ser.write("D0,"+str(hex(512*i)[2:])+"\n") 69 | zz=time.time() 70 | i=i+1 71 | print 'Dumping address '+str(hex(512*i)[2:])+' '+str(256*i/1000)+'kB '+str(len(dumpf))+' mit einer Geschwindigkeit von '+speed+'byte/sek' 72 | # if len(dumpf)%36!=0: 73 | # print 'Dumping error' 74 | # print dumpf 75 | # break 76 | except: 77 | print 'Saving this shit right where it belongs!' 78 | # mem.close() 79 | break 80 | 81 | print time.time()-zeit 82 | fooR=re.compile('\d\d\d\d\d\d\d\d\s+(.+)\r') 83 | foo=fooR.findall(dumpf) 84 | for line in foo: 85 | mem.write(re.sub(' ','',line).decode("hex")) 86 | mem.close 87 | print 'Succesfully dumped file' 88 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | argparse==1.2.1 2 | pyserial==2.7 3 | -------------------------------------------------------------------------------- /see-append.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python2 2 | #Dumps the memory of a seagate hd using the jumper pin serial interface 3 | import serial 4 | import sys,os,re,argparse 5 | import time 6 | from wgetstyle import * 7 | 8 | debug=0 9 | #automagicly set to 115200 baud 10 | fast=1 11 | #1 is slow 0 is fastest 0.1 is the sweetspot 12 | timeout=0.2 13 | benchmark=1 14 | writing=0 15 | 16 | try: 17 | device=sys.argv[1] 18 | dumpfile=sys.argv[2] 19 | baud=sys.argv[3] 20 | memf=open(dumpfile,'r+') 21 | fileend=len(memf.read()) 22 | except: 23 | print 'Usage:' 24 | print sys.argv[0]+' device dumpfile baud\n' 25 | print 'Default baud should be 38400 maximum is 115200\n' 26 | quit() 27 | 28 | def send(ser,command): 29 | ser.write(command+"\n") 30 | inco="" 31 | while 1: 32 | try: 33 | arr=ser.readline() 34 | if arr!="": 35 | inco=inco+arr 36 | else: 37 | if debug>=2: 38 | print inco 39 | modus=re.findall('F3 (.)>',inco) 40 | break 41 | #print 'Next command' 42 | except: 43 | print 'Exception! (in send)' 44 | if writing==1: 45 | memf.close() 46 | break 47 | return inco,modus 48 | 49 | def get_modus(ser): 50 | inco,modus=send(ser,"") 51 | return modus[0] 52 | 53 | def set_baud(ser,baud): 54 | modus=get_modus(ser) 55 | print 'Setting baud to '+str(baud) 56 | if modus!="T": 57 | print 'Changing mode to T' 58 | send(ser,"/T") 59 | send(ser,"B"+str(baud)) 60 | ser = serial.Serial(port=device, baudrate=baud, bytesize=8,parity='N',stopbits=1,timeout=timeout) 61 | send(ser,"/"+modus) 62 | return ser 63 | 64 | def init(device,baud,fast=fast): 65 | ser = serial.Serial(port=device, baudrate=baud, bytesize=8,parity='N',stopbits=1,timeout=timeout) 66 | #Initialize the command line 67 | # print ser.inWaiting() 68 | # print dir(ser) 69 | # if send(ser,"\n")[1]==[]: 70 | # print 'Got no modus bad' 71 | # quit() 72 | print send(ser,"\n") 73 | print send(ser,"\x1A")[1] 74 | if baud=="38400" and fast==1: 75 | baud=115200 76 | try: 77 | set_baud(ser,baud) 78 | ser = serial.Serial(port=device, baudrate=baud, bytesize=8,parity='N',stopbits=1,timeout=timeout) 79 | except: 80 | print 'You probably already are on 115200 baud' 81 | send(ser,"/1") 82 | return ser 83 | 84 | def parse(buff): 85 | hex="" 86 | bin="" 87 | fooR=re.compile('[0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F]\s+(.+)\r') 88 | parsed=fooR.findall(buff) 89 | for line in parsed: 90 | hex=hex+re.sub(' ','',line) 91 | try: 92 | bin=hex.decode("hex") 93 | except: 94 | print 'Parse failed' 95 | return hex,bin 96 | 97 | def display_buffer(ser,num): 98 | #num xxxx 99 | foo,bar=send(ser,'B'+str(num)) 100 | return parse(foo) 101 | 102 | def display_memory(ser,num1,num2): 103 | #num1 xx, num2 yyyy 104 | looped=0 105 | if debug>=1: 106 | print 'D'+str(num1)+","+str(num2)+" - " 107 | foo,bar=send(ser,'D'+str(num1)+","+str(num2)) 108 | parsed=parse(foo) 109 | if len(parsed[1])==0: 110 | print 'Got nothing trying again :/' 111 | if looped>10: 112 | print "Seems like we're stuck - quitting" 113 | memf.close() 114 | quit() 115 | looped=looped+1 116 | parsed=display_memory(ser,num1,num2) 117 | if len(parsed[1])!=512: 118 | print 'Got the wrong size!!!!!!1111' 119 | parsed=display_memory(ser,num1,num2) 120 | return parsed 121 | 122 | def dump_memory(ser,dumpfile): 123 | writing=1 124 | k=0 125 | total=(64*128*512)/1024.0 126 | stime=time.time() #start time 127 | print 'Continuing memory dump' 128 | for j in range(0,64): 129 | for i in range(0,128): 130 | k=k+1 131 | zz=time.time() 132 | if k>fileend/0x200: 133 | mem=display_memory(ser,hex(j)[2:],hex(i*0x200)[2:])[1] 134 | if benchmark==1: 135 | size=(k*512)/1024.0 136 | # speed=round(512/(time.time()-zz),2) 137 | percentage=round(100.0/total*size,2) 138 | minleft=round((time.time()-stime)/k*(247*128-k)/60,2) 139 | if debug==0: 140 | progress_bar(time.time()-stime,size*1024,total*1024) 141 | elif debug>0: 142 | print 'time:'+str(time.time()-stime) 143 | print 'size:'+str(size) 144 | print 'total:'+str(total) 145 | if k>fileend/0x200: 146 | memf.write(mem) 147 | memf.close() 148 | writing=0 149 | 150 | def dump_buffer(ser,dumpfile): 151 | writing=1 152 | k=0 153 | total=(65535*512)/1024.0 154 | stime=time.time() #start time 155 | for i in range(0,65535): 156 | k=k+1 157 | zz=time.time() 158 | if k>fileend/0x200: 159 | mem=display_buffer(ser,hex(i)[2:])[1] 160 | size=(k*512)/1024.0 161 | if benchmark==1: 162 | progress_bar(time.time()-stime,size*1024,total*1024) 163 | if k>fileend/0x200: 164 | memf.write(mem) 165 | memf.close() 166 | writing=0 167 | 168 | ser=init(device,baud) 169 | #print send(ser,'') 170 | #print display_buffer(ser,00)[0] 171 | try: 172 | modus=get_modus(ser) 173 | except: 174 | print "Couldn't even get the modus - quitting" 175 | if debug<2: 176 | print 'Try it using debug=2' 177 | quit() 178 | if modus!="1": 179 | print 'Somethings not right here' 180 | quit() 181 | #print display_memory(ser,'15','C000') 182 | dump_buffer(ser,dumpfile) 183 | #dump_buffer(ser,dumpfile) 184 | print 185 | -------------------------------------------------------------------------------- /see.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python2 2 | #Dumps the memory of a seagate hd using the jumper pin serial interface 3 | import serial 4 | import sys,os,re,argparse 5 | import time 6 | from wgetstyle import * 7 | 8 | debug=0 9 | #automagicly set to 115200 baud 10 | fast=1 11 | #1 is slow 0 is fastest 0.1 is the sweetspot 12 | timeout=0.01 13 | benchmark=1 14 | writing=0 15 | 16 | try: 17 | device=sys.argv[1] 18 | dumpfile=sys.argv[2] 19 | baud=sys.argv[3] 20 | memf=open(dumpfile,'w') 21 | except: 22 | print 'Usage:' 23 | print sys.argv[0]+' device dumpfile baud\n' 24 | print 'Default baud should be 38400 maximum is 115200\n' 25 | quit() 26 | 27 | def send(ser,command): 28 | ser.write(command+"\n") 29 | inco="" 30 | while 1: 31 | try: 32 | arr=ser.readline() 33 | if arr!="": 34 | inco=inco+arr 35 | else: 36 | if debug>=2: 37 | print inco 38 | modus=re.findall('F3 (.)>',inco) 39 | break 40 | #print 'Next command' 41 | except: 42 | print 'Exception! (in send)' 43 | if writing==1: 44 | memf.close() 45 | break 46 | return inco,modus 47 | 48 | def get_modus(ser): 49 | inco,modus=send(ser,"") 50 | return modus[0] 51 | 52 | def set_baud(ser,baud): 53 | modus=get_modus(ser) 54 | print 'Setting baud to '+str(baud) 55 | if modus!="T": 56 | print 'Changing mode to T' 57 | send(ser,"/T") 58 | send(ser,"B"+str(baud)) 59 | ser = serial.Serial(port=device, baudrate=baud, bytesize=8,parity='N',stopbits=1,timeout=timeout) 60 | send(ser,"/"+modus) 61 | return ser 62 | 63 | def init(device,baud,fast=fast): 64 | ser = serial.Serial(port=device, baudrate=baud, bytesize=8,parity='N',stopbits=1,timeout=timeout) 65 | #Initialize the command line 66 | # print ser.inWaiting() 67 | # print dir(ser) 68 | # if send(ser,"\n")[1]==[]: 69 | # print 'Got no modus bad' 70 | # quit() 71 | # print send(ser,"\n")[1] 72 | print send(ser,"\x1A")[1] 73 | if baud=="38400" and fast==1: 74 | baud=115200 75 | try: 76 | set_baud(ser,baud) 77 | ser = serial.Serial(port=device, baudrate=baud, bytesize=8,parity='N',stopbits=1,timeout=timeout) 78 | except: 79 | print 'You probably already are on 115200 baud' 80 | send(ser,"/1") 81 | return ser 82 | 83 | def parse(buff): 84 | hex="" 85 | fooR=re.compile('[0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F]\s+(.+)\r') 86 | parsed=fooR.findall(buff) 87 | for line in parsed: 88 | hex=hex+re.sub(' ','',line) 89 | bin=hex.decode("hex") 90 | return hex,bin 91 | 92 | def display_buffer(ser,num): 93 | #num xxxx 94 | foo,bar=send(ser,'B'+str(num)) 95 | return parse(foo) 96 | 97 | def display_memory(ser,num1,num2): 98 | #num1 xx, num2 yyyy 99 | looped=0 100 | if debug>=1: 101 | print 'D'+str(num1)+","+str(num2)+" - " 102 | foo,bar=send(ser,'D'+str(num1)+","+str(num2)) 103 | parsed=parse(foo) 104 | if len(parsed[1])==0: 105 | print 'Got nothing trying again :/' 106 | if looped>10: 107 | print "Seems like we're stuck - quitting" 108 | memf.close() 109 | quit() 110 | looped=looped+1 111 | parsed=display_memory(ser,num1,num2) 112 | if len(parsed[1])!=512: 113 | print 'Got the wrong size!!!!!!1111' 114 | parsed=display_memory(ser,num1,num2) 115 | return parsed 116 | 117 | def dump_memory(ser,dumpfile): 118 | writing=1 119 | k=0 120 | total=(64*128*512)/1024.0 121 | stime=time.time() #start time 122 | print 'Starting memory dump' 123 | for j in range(0,64): 124 | for i in range(0,128): 125 | k=k+1 126 | zz=time.time() 127 | mem=display_memory(ser,hex(j)[2:],hex(i*0x200)[2:])[1] 128 | if benchmark==1: 129 | size=(k*512)/1024.0 130 | speed=round(512/(time.time()-zz),2) 131 | percentage=round(100.0/total*size,2) 132 | minleft=round((time.time()-stime)/k*(247*128-k)/60,2) 133 | if debug==0: 134 | progress_bar(time.time()-stime,size*1024,total*1024) 135 | elif debug>0: 136 | print 'time:'+str(time.time()-stime) 137 | print 'size:'+str(size) 138 | print 'total:'+str(total) 139 | memf.write(mem) 140 | memf.close() 141 | writing=0 142 | 143 | def dump_buffer(ser,dumpfile): 144 | writing=1 145 | k=0 146 | total=(65535*512)/1024.0 147 | stime=time.time() #start time 148 | for i in range(0,65535): 149 | k=k+1 150 | zz=time.time() 151 | mem=display_buffer(ser,hex(i)[2:])[1] 152 | size=(k*512)/1024.0 153 | if benchmark==1: 154 | progress_bar(time.time()-stime,size*1024,total*1024) 155 | memf.write(mem) 156 | memf.close() 157 | writing=0 158 | 159 | ser=init(device,baud) 160 | #print send(ser,'') 161 | #print display_buffer(ser,00)[0] 162 | try: 163 | modus=get_modus(ser) 164 | except: 165 | print "Couldn't even get the modus - quitting" 166 | if debug<2: 167 | print 'Try it using debug=2' 168 | quit() 169 | if modus!="1": 170 | print 'Somethings not right here' 171 | quit() 172 | #print display_memory(ser,'15','C000') 173 | dump_memory(ser,dumpfile) 174 | #dump_buffer(ser,dumpfile) 175 | print 176 | -------------------------------------------------------------------------------- /wgetstyle.py: -------------------------------------------------------------------------------- 1 | import os,sys,re 2 | from math import ceil 3 | #wget style progress bar library :) 0.1 4 | #rows, columns = os.popen('stty size', 'r').read().split() 5 | stypes=['byte','KB','MB','GB','TB'] 6 | ttypes=[['ms',1000],['s',60],['m',60],['h',24],['d',365],['y','10']] 7 | 8 | def correctsize(num,stype): 9 | if num>=1000: 10 | num=num/1000.0 11 | stype=stype+1 12 | if num>=1000: 13 | num,stype=correctsize(num,stype) 14 | return num,stype 15 | 16 | def correcttime(num,ttype=1): 17 | if num>ttypes[ttype][1]: 18 | num=num/1.0/ttypes[ttype][1] 19 | ttype=ttype+1 20 | if num>ttypes[ttype][1]: 21 | num,ttype=correcttime(num,ttype) 22 | else: 23 | num=round(num,0)+float(round(ttypes[ttype-1][1]/100.0*((num-ceil(num)+1)*100.0),0)/100.0) 24 | return num,ttype 25 | 26 | def foo_to_byte(num,stype): 27 | #decimal vs binary 28 | if stype>1: 29 | num=num/1000 30 | stype=stype-1 31 | elif stype<1: 32 | num=num*1000 33 | stype=stype+1 34 | if stype!=1: 35 | num,stype=foo_to_byte(num,stype) 36 | return num 37 | 38 | def dotit(num): 39 | addnull=(3-len(str(num))%3)%3 40 | newnum="" 41 | if addnull!=3: 42 | for i in range(0,addnull): 43 | num='0'+str(num) 44 | for i in re.findall('(.?.?.)',str(num)): 45 | newnum=newnum+'.'+i 46 | return newnum[addnull+1:] 47 | 48 | 49 | def progress_bar(dtime,nfile,total=0,k=0,stype=1): 50 | rows, columns = os.popen('stty size', 'r').read().split() 51 | columns=int(columns) 52 | for i in range(0,columns): 53 | sys.stdout.write("\b") 54 | perc=100*int(nfile)/int(total) 55 | #stype 0=bit,1=byte,2=kbyte,3=mbyte,4=gbyte - shouldn't be changed (time is in seconds) 56 | if dtime==0: 57 | dtime=0.0001 58 | speed=float(nfile)/float(dtime) 59 | speed,sptype=correctsize(speed,stype) 60 | space=columns-42 61 | eq=int(round(space/100.0*perc,0)) 62 | #penis 63 | if perc<10: 64 | line=' '+str(perc)+'% [' 65 | elif perc>99: 66 | line='100%[' 67 | else: 68 | line=str(perc)+'% [' 69 | for i in range(0,eq): 70 | line=line+"=" 71 | line=line+">" 72 | for i in range(0,space-eq): 73 | line=line+" " 74 | #bytesize 75 | bytes=foo_to_byte(nfile,stype) 76 | line=line+"] " 77 | foo=" "+dotit(nfile) 78 | # print type(len(dotit(total))+3-len(foo)) 79 | for i in range(0,len(dotit(total))+3-len(foo)): 80 | foo=foo+" " 81 | line=line+foo 82 | #speed 83 | if int(nfile)==0: 84 | nfile=0.0001 85 | eta=float(dtime)/float(nfile)*(int(total)-int(nfile)) 86 | eta,ttype=correcttime(eta) 87 | speed=str(round(speed,3-len(str(int(ceil(speed)-1))))) 88 | # if len(speed)==2: 89 | # speed=speed+'0' 90 | # elif len(speed)==1: 91 | # speed=speed+'00' 92 | 93 | line=line+str(speed)+stypes[stype]+'/s ETA '+str(round(eta,2))+ttypes[ttype][0] 94 | for i in range(0,columns-len(line)): 95 | line=line+" " 96 | sys.stdout.write(line) 97 | sys.stdout.flush() 98 | 99 | 100 | #progress_bar(int(sys.argv[1]),sys.argv[2],sys.argv[3]) 101 | 102 | -------------------------------------------------------------------------------- /wip/extract-seagate-password.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # 3 | # Extract user and master passwords from Seagate hard drive ROM dumps 4 | # 5 | # Author: Derrick Karpo 6 | # Date: February 26, 2014 7 | # 8 | 9 | import argparse 10 | from binascii import hexlify, unhexlify 11 | from re import search 12 | import sys 13 | 14 | 15 | def findPassword(romdump): 16 | # define the password regex 17 | PATTERN = b'00000000edfe0d90ffff.+?0c54.{8}(.{64})(.{64})' 18 | 19 | # open the ROM dump and attempt to locate the user and master passwords 20 | try: 21 | rom = hexlify(romdump.read()) 22 | password = search(PATTERN, rom) 23 | 24 | if not password: 25 | sys.exit("No user or master passwords found in '%s'" % romdump.name) 26 | 27 | # dump out the found passwords 28 | master = password.group(1) 29 | user = password.group(2) 30 | print('{0:>15}: {1:}'.format("File name", romdump.name)) 31 | print('{0:>15}: {1:.0f}'.format("Byte offset", password.start()/2)) 32 | print('{0:>15}: {1:}'.format("master HEX pw", master)) 33 | print('{0:>15}: {1:}'.format("master ASCII pw", unhexlify(master))) 34 | print('{0:>15}: {1:}'.format("user HEX pw", user)) 35 | print('{0:>15}: {1:}'.format("user ASCII pw", unhexlify(user))) 36 | print() 37 | except IOError: 38 | sys.exit("Erroring processing file: %s" % romdump) 39 | 40 | 41 | def main(): 42 | # setup the argument parser for the command line arguments 43 | parser = argparse.ArgumentParser( 44 | prog='extract-seagate-password.py', 45 | description='Extract user and master passwords from Seagate hard drive ROM dumps.') 46 | parser.add_argument('romdump', nargs='+', 47 | type=argparse.FileType('rb'), 48 | help='Seagate hard drive ROM dump file(s)') 49 | parser.add_argument('-v', action='version', 50 | version='%(prog)s 0.2', help='Version') 51 | args = parser.parse_args() 52 | 53 | # output help and exit when no arguments are given 54 | if len(sys.argv) == 1: 55 | parser.print_help() 56 | return 57 | 58 | # attempt to locate the user and master passwords 59 | for fn in args.romdump: 60 | findPassword(fn) 61 | 62 | 63 | if __name__ == "__main__": 64 | main() 65 | -------------------------------------------------------------------------------- /wip/seaget.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python2 2 | # clean rewrite and combination of all my old python scripts 3 | # TODO: 4 | # - get basic functions [] 5 | # - add advances functions like: 6 | # looking for password at address $foo [] 7 | # write to buffer/memory [] 8 | # search for password without dumping [] 9 | # add devices with known address [] 10 | 11 | from __future__ import print_function 12 | 13 | from argparse import ArgumentParser 14 | import math 15 | import re 16 | import sys 17 | import time 18 | from wgetstyle import progress_bar 19 | 20 | try: 21 | from serial import Serial 22 | except ImportError: 23 | sys.exit('You have to install pyserial') 24 | 25 | 26 | def main(): 27 | args = get_arguments() 28 | see = SeaGet(args.baud, args.cont, args.filename, args.device, args.new_baud) 29 | if args.dumptype[0]=='memory': 30 | see.dump_memory(args.filename, args.cont) 31 | elif args.dumptype[0]=='buffer': 32 | see.dump_buffer(args.filename, args.cont) 33 | 34 | def get_arguments(): 35 | parser = ArgumentParser(description='Dump memory/buffer of a seagate hd using a serial connection.') 36 | parser.add_argument('--dumptype', metavar='memory/buffer', nargs=1, default=['memory'], help='What gets dumped') 37 | parser.add_argument('--baud', metavar=38400, default=38400, help='current baud rate [38400,115200]') 38 | parser.add_argument('--new-baud', metavar=115200, default=False, help='set new baud rate [38400,115200]') 39 | parser.add_argument('-c', dest='cont', action='store_const', const=True, help='Continue dump') 40 | parser.add_argument('--device', metavar='/dev/ttyUSB0', default='/dev/ttyUSB0', help='the serial device you use') 41 | parser.add_argument('filename', metavar='dumpfile', help='the name of the dump file, duh') 42 | return parser.parse_args() 43 | 44 | 45 | class SeaGet(): 46 | 47 | def __init__(self, baud, cont, filename, device, new_baud, debug=0, timeout=0.004, benchmark=0): 48 | self.debug = debug 49 | self.timeout = timeout 50 | self.benchmark = benchmark 51 | self.device = device 52 | self.ser = Serial(port=self.device, baudrate=baud, bytesize=8, parity='N', stopbits=1, timeout=self.timeout) 53 | 54 | #start diagnostic mode 55 | if self.debug > 0: 56 | print('Start diagnostic mode') 57 | _, mode = self.send("\x1A") 58 | if mode not in ['1', 'T']: 59 | sys.exit("Something has gone wrong. Modus is %s (expected 1 or T)" % mode) 60 | 61 | #if you want a different baud rate you get it! 62 | if new_baud: 63 | if self.debug > 0: 64 | print('Set new baud rate') 65 | self.set_baud(new_baud) 66 | baud = new_baud 67 | #set the right mode to access memory and buffer 68 | if self.debug > 0: 69 | print('Set mode /1') 70 | incoming, mode = self.send("/1") 71 | if mode != "1": 72 | exit_msgs = ["Couldn't set modus to 1. Failed with %s" % incoming, ] 73 | if re.match('Input Command Error', incoming) and baud != 38400: 74 | exit_msgs.append('You probably set a higher baud rate, on a hd that has a bug.') 75 | exit_msgs.append('Turn the hd off and on again and try the default baud rate 38400.') 76 | sys.exit('\n'.join(exit_msgs)) 77 | 78 | def send(self, command): 79 | #if this doesn't work for you try setting a greater timeout (to be on the safe side try 1) 80 | #zc is the zerocounter and used to prevent it from going forever 81 | incom = [""] 82 | line = True 83 | zc = 0 84 | self.ser.write(command + "\n") 85 | while 1: 86 | try: 87 | line = self.ser.readline() 88 | if line == "": 89 | zc += 1 90 | else: 91 | zc = 0 92 | if zc == 500: 93 | break 94 | incom.append(line) 95 | except: 96 | sys.exit('Failed to read line. Maybe the timeout is too low.') 97 | 98 | incom = "".join(incom) 99 | #You can (and have to) set different modi for the hd. 100 | #a different modus means you get a different set of commands 101 | #checking the modi after every command can be used for debugging and/or to verify that a command got executed correctly 102 | try: 103 | modus = re.findall('F3 (.)>', incom) 104 | modus = modus[len(modus)-1] 105 | except: 106 | exit_msgs = ["Failed to execute regex.", 107 | "This usually means that you didn't get the whole message or nothing at all.", 108 | "Check your baud rate and timeout/zc.", 109 | incom, ] 110 | sys.exit(exit_msgs) 111 | 112 | return incom, modus 113 | 114 | def get_modus(self): 115 | return self.send("")[1] 116 | 117 | def set_baud(self, newbaud): 118 | modus = self.get_modus() 119 | print('Setting baud to %s' % newbaud) 120 | if modus != "T": 121 | print('Changing mode to T') 122 | self.send("/T") 123 | self.send("B"+str(newbaud)) 124 | self.ser = Serial(port=self.device, baudrate=newbaud, bytesize=8, parity='N', stopbits=1, timeout=self.timeout) 125 | newmodus = self.send("/"+modus)[1] 126 | 127 | return modus == newmodus 128 | 129 | def parse(self, buff): 130 | hex = "" 131 | fooR = re.compile('[0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F][0-9A-F]\s+(.+)\r') 132 | parsed = fooR.findall(buff) 133 | # for line in parsed: 134 | # hex=hex+re.sub(' ','',line) 135 | hex = re.sub(' ', '', ''.join(parsed)) 136 | bin = hex.decode("hex") 137 | return hex, bin 138 | 139 | def read_buffer(self, hexa): 140 | #hexa xxxx 141 | #hexa is the address you want to read in hex 142 | res, modus = self.send('B'+str(hexa)) 143 | return self.parse(res) 144 | 145 | def read_memory(self, hexa, hexb): 146 | #hexa xx 147 | #hexb yyyy 148 | #it always gives you 256bytes 149 | resp, modus = self.send('D'+str(hexa)+','+str(hexb)) 150 | parsed = self.parse(resp) 151 | if len(parsed[1]) != 512: 152 | #should never happen,but could if timeout is too low 153 | return False, False 154 | return parsed 155 | 156 | def dump_memory(self, filename, cont): 157 | if cont: 158 | memf = open(filename, 'r+') 159 | fsize = len(memf.read()) 160 | if fsize % 512 != 0: 161 | sys.exit('%s seems to be corrupted (wrong file size)' % filename) 162 | 163 | sj = math.trunc(fsize/512/64) 164 | si = fsize/512-64*sj 165 | if self.debug > 0: 166 | print('Starting from %s %s' % (sj, si)) 167 | else: 168 | memf = open(filename, 'w') 169 | fsize = 0 170 | sj, si = 0, 0 171 | k = fsize/512 172 | total = (64*128*512)/1000.0 173 | stime = time.time() # start time 174 | 175 | print('Starting memory dump') 176 | for j in range(sj, 64): 177 | for i in range(si, 128): 178 | k += 1 179 | zz = time.time() 180 | memf.write(self.read_memory(hex(j)[2:], hex(i*0x200)[2:])[1]) 181 | size = (k*512)/1000.0 182 | if self.benchmark == 1: 183 | speed = round(512/(time.time()-zz), 2) 184 | percentage = round(100.0/total*size, 2) 185 | minleft = round((time.time()-stime)/k*(247*128-k)/60, 2) 186 | progress_bar(time.time()-stime, size*1000, total*1000) 187 | memf.close() 188 | 189 | def dump_buffer(self,filename,cont): 190 | #not tested yet 191 | #so it's "experimental" I guess... 192 | #and I wouldn't use continue yet 193 | #and the file dump get's much too big because they loop the buffer over and over and I'm not quite sure if the buffer has always the same size 194 | if cont: 195 | bufff = open(filename, 'r+') 196 | fsize = len(bufff.read()) 197 | if fsize % 512 != 0: 198 | sys.exit('%s seems to be corrupted (wrong file size)' % filename) 199 | sp = math.trunc(fsize/512) 200 | if self.debug > 0: 201 | print('Starting from %s' % (sp)) 202 | else: 203 | bufff = open(filename, 'w') 204 | fsize = 0 205 | sp = 0 206 | k = fsize/512 207 | total = (65535*512)/1000.0 208 | stime = time.time() # start time 209 | 210 | print ('Start buffer dump') 211 | 212 | for i in range(sp,65535): 213 | k += 1 214 | zz = time.time() 215 | bufff.write(self.read_buffer(hex(i)[2:])[1]) 216 | size = (k*512)/1000.0 217 | if self.benchmark == 1: 218 | speed = round(512/(time.time()-zz), 2) 219 | percentage = round(100.0/total*size, 2) 220 | minleft = round((time.time()-stime)/k*(247*128-k)/60, 2) 221 | progress_bar(time.time()-stime, size*1000, total*1000) 222 | 223 | if __name__ == '__main__': 224 | main() 225 | --------------------------------------------------------------------------------