{"id":63,"date":"2011-08-31T15:50:05","date_gmt":"2011-08-31T15:50:05","guid":{"rendered":"http:\/\/www.gironsec.com\/blog\/?p=63"},"modified":"2013-10-27T10:56:49","modified_gmt":"2013-10-27T10:56:49","slug":"file-locks-and-win32","status":"publish","type":"post","link":"https:\/\/www.gironsec.com\/blog\/2011\/08\/file-locks-and-win32\/","title":{"rendered":"File Locks and win32"},"content":{"rendered":"<p>The other day I was watching some stuff on a video stream site. It was a knockoff of the all popular youtube, but this one took extra steps to make sure you could not download their videos.<\/p>\n<p>The easiest method for me to download videos from sites like this is to just check the temp internet folder and copy the file from there. This site was different. The file was in use by firefox the entire time (IE as well) and could not be copied or opened or written to without getting the classic &#8216;access denied&#8217; message. Windows as we all know wont let you delete files that are in use including DLL&#8217;s and temp files (as we&#8217;ve all seen with malware). I believe it used a method similar to this:<\/p>\n<p>http:\/\/msdn.microsoft.com\/en-us\/library\/aa365203%28v=vs.85%29.aspx<\/p>\n<h4>LockFileEx Function<\/h4>\n<pre>BOOL WINAPI LockFileEx(\r\n  __in\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0HANDLE hFile,\r\n  __in\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0DWORD dwFlags,\r\n  __reserved\u00a0\u00a0DWORD dwReserved,\r\n  __in\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0DWORD nNumberOfBytesToLockLow,\r\n  __in\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0DWORD nNumberOfBytesToLockHigh,\r\n  __inout\u00a0\u00a0\u00a0\u00a0\u00a0LPOVERLAPPED lpOverlapped\r\n);<\/pre>\n<div>Whats it do? Locks the specified file for exclusive access by the calling process. This function can operate either synchronously or asynchronously and can request either an exclusive or a shared lock.<\/div>\n<div>The second parameter, specifically the double word value is what gets me. When set to LOCKFILE_EXCLUSIVE_LOCK (0x00000002) any access to the shared segment of the file (which could be the whole damn thing) will result in our access denied message.<\/div>\n<div>I tried numerous little techniques to get around this such as attaching to the process and attempting to insert code to waive the lock with UnLockFileEx(), but it failed and is too damn hard to pull off. Another idea I had was to just read the damn file from memory, but then I would be left with a HUGE chunk of hex data that&#8217;s supposed to be the video. I had almost given up hope when I remembered something about Posix &#8211; symlinks.<\/div>\n<div>Windows doesn&#8217;t have symlinks per say, but rather HardLinks. A little known fact about hard links is that when the file you link to is deleted, the contents of the file are copied over, no questions asked to the file you linked from.<\/div>\n<div>Here is the function and args:<\/div>\n<h4>CreateHardLink<\/h4>\n<div>http:\/\/msdn.microsoft.com\/en-us\/library\/aa363860%28v=vs.85%29.aspx<\/div>\n<div>\n<p>BOOL WINAPI CreateHardLink( __in\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0LPCTSTR lpFileName, __in\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0LPCTSTR lpExistingFileName, __reserved\u00a0\u00a0LPSECURITY_ATTRIBUTES lpSecurityAttributes );<\/p>\n<p>Seems self explanatory. Funny enough the security attributes param is supposed to be null since they never implemented it (yay).<\/p>\n<p>So what do we do? C to the rescue:<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #f0f0f0; overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;\">\n<pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #007020\">#include &lt;windows.h&gt;<\/span>\r\n<span style=\"color: #007020\">#include &lt;stdio.h&gt;<\/span>\r\n\r\n<span style=\"color: #902000\">int<\/span> <span style=\"color: #06287e\">main<\/span>(<span style=\"color: #902000\">int<\/span> argc, <span style=\"color: #902000\">char<\/span> <span style=\"color: #666666\">**<\/span>argv[])\r\n{\r\n\r\n<span style=\"color: #007020; font-weight: bold\">if<\/span>(argc <span style=\"color: #666666\">&lt;<\/span> <span style=\"color: #40a070\">2<\/span>)\r\n{\r\nprintf(<span style=\"color: #4070a0\">&quot;usage is %s path + file to locked file<\/span><span style=\"color: #4070a0; font-weight: bold\">\\r\\n<\/span><span style=\"color: #4070a0\">&quot;<\/span>,argv[<span style=\"color: #40a070\">0<\/span>]);\r\n\r\n<span style=\"color: #007020; font-weight: bold\">return<\/span> <span style=\"color: #40a070\">0<\/span>;\r\n\r\n}\r\n<span style=\"color: #007020; font-weight: bold\">else<\/span>\r\n{\r\n<span style=\"color: #902000\">char<\/span> <span style=\"color: #666666\">*<\/span>lockedfilename <span style=\"color: #666666\">=<\/span> argv[<span style=\"color: #40a070\">1<\/span>];\r\n<span style=\"color: #902000\">char<\/span> <span style=\"color: #666666\">*<\/span>newfilename <span style=\"color: #666666\">=<\/span> argv[<span style=\"color: #40a070\">2<\/span>];\r\n\r\n<span style=\"color: #007020; font-weight: bold\">if<\/span>(CreateHardLink(newfilename,lockedfilename,<span style=\"color: #007020\">NULL<\/span>))\r\n{\r\nprintf(<span style=\"color: #4070a0\">&quot;Hard Link created between %s and %s<\/span><span style=\"color: #4070a0; font-weight: bold\">\\r\\n<\/span><span style=\"color: #4070a0\">&quot;<\/span>,lockedfilename,newfilename);\r\nsystem(<span style=\"color: #4070a0\">&quot;pause&quot;<\/span>);\r\n<span style=\"color: #007020; font-weight: bold\">return<\/span> <span style=\"color: #40a070\">1<\/span>;\r\n}\r\n<span style=\"color: #007020; font-weight: bold\">else<\/span>\r\n{\r\nprintf(<span style=\"color: #4070a0\">&quot;something went wrong, you prolly specified a bad file or something<\/span><span style=\"color: #4070a0; font-weight: bold\">\\r\\n<\/span><span style=\"color: #4070a0\">&quot;<\/span>);\r\n<span style=\"color: #007020; font-weight: bold\">return<\/span> <span style=\"color: #40a070\">0<\/span>;\r\n}\r\n}\r\n}\r\n}\r\n<\/pre>\n<\/div>\n<p>If there&#8217;s a syntax error in this code, I&#8217;m sorry. I wrote the C off the top of my head. My little program allows you to save locked files to a new location. Further modifications to the code would be to call DeleteFile() or something like that after the link is created. Oh well.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>The other day I was watching some stuff on a video stream site. It was a knockoff of the all popular youtube, but this one took extra steps to make sure you could not download their videos. The easiest method for me to download videos from sites like this is to just check the temp [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/www.gironsec.com\/blog\/wp-json\/wp\/v2\/posts\/63"}],"collection":[{"href":"https:\/\/www.gironsec.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.gironsec.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.gironsec.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.gironsec.com\/blog\/wp-json\/wp\/v2\/comments?post=63"}],"version-history":[{"count":4,"href":"https:\/\/www.gironsec.com\/blog\/wp-json\/wp\/v2\/posts\/63\/revisions"}],"predecessor-version":[{"id":568,"href":"https:\/\/www.gironsec.com\/blog\/wp-json\/wp\/v2\/posts\/63\/revisions\/568"}],"wp:attachment":[{"href":"https:\/\/www.gironsec.com\/blog\/wp-json\/wp\/v2\/media?parent=63"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.gironsec.com\/blog\/wp-json\/wp\/v2\/categories?post=63"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.gironsec.com\/blog\/wp-json\/wp\/v2\/tags?post=63"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}